From 314c4f782f434dc799a732036f273bbc9d5c5f3a Mon Sep 17 00:00:00 2001 From: Daniil Suleiman <31325372+sulemanof@users.noreply.github.com> Date: Wed, 8 Apr 2020 12:00:13 +0300 Subject: [PATCH 01/40] [NP] Vis Default Editor plugin (#62475) * Move the default_editor to NP * Fix paths * Import styles through the visualize * Other fixes * Fix ip_ranges exhaustive-deps array * Fix filters and extend bounds * Other fixes * Fix date_ranges tests * Use useMount on first render Co-authored-by: Elastic Machine --- .eslintrc.js | 20 ---- .i18nrc.json | 2 +- .../public/components/editor/controls_tab.tsx | 2 +- .../public/components/editor/options_tab.tsx | 2 +- .../kibana/public/visualize/_index.scss | 3 + .../public/visualize/kibana_services.ts | 2 +- .../kibana/public/visualize/plugin.ts | 2 +- .../public/components/region_map_options.tsx | 2 +- .../region_map/public/region_map_type.js | 2 +- .../public/components/tile_map_options.tsx | 2 +- .../tile_map/public/tile_map_type.js | 2 +- .../core_plugins/vis_default_editor/index.ts | 42 -------- .../vis_default_editor/package.json | 4 - .../public/markdown_options.tsx | 2 +- .../vis_type_markdown/public/markdown_vis.ts | 2 +- .../public/settings_options.tsx | 2 +- .../public/components/metric_vis_options.tsx | 2 +- .../public/metric_vis_fn.test.ts | 4 - .../public/metric_vis_type.test.ts | 4 - .../vis_type_metric/public/metric_vis_type.ts | 2 +- .../public/components/table_vis_options.tsx | 2 +- .../vis_type_table/public/table_vis_type.ts | 2 +- .../public/components/tag_cloud_options.tsx | 2 +- .../public/tag_cloud_type.ts | 2 +- .../public/components/timelion_interval.tsx | 2 +- .../public/timelion_options.tsx | 2 +- .../public/timelion_vis_type.tsx | 2 +- .../public/components/vega_vis_editor.tsx | 2 +- .../vis_type_vega/public/vega_type.ts | 3 +- .../vis_type_vislib/public/area.ts | 2 +- .../components/common/basic_options.tsx | 2 +- .../public/components/common/color_ranges.tsx | 5 +- .../public/components/common/color_schema.tsx | 2 +- .../components/common/validation_wrapper.tsx | 2 +- .../public/components/options/gauge/index.tsx | 2 +- .../components/options/heatmap/index.tsx | 2 +- .../options/heatmap/labels_panel.tsx | 2 +- .../metrics_axes/category_axis_panel.tsx | 2 +- .../public/components/options/pie.tsx | 2 +- .../options/point_series/grid_panel.tsx | 2 +- .../vis_type_vislib/public/gauge.ts | 2 +- .../vis_type_vislib/public/goal.ts | 2 +- .../vis_type_vislib/public/heatmap.ts | 2 +- .../vis_type_vislib/public/histogram.ts | 2 +- .../vis_type_vislib/public/horizontal_bar.ts | 2 +- .../vis_type_vislib/public/line.ts | 2 +- .../vis_type_vislib/public/pie.ts | 2 +- .../public/utils/common_config.tsx | 2 +- src/plugins/vis_default_editor/README.md | 16 ++++ .../vis_default_editor/public/_agg.scss | 0 .../public/_agg_params.scss | 0 .../vis_default_editor/public/_default.scss | 0 .../vis_default_editor/public/_sidebar.scss | 0 .../__snapshots__/agg.test.tsx.snap | 0 .../__snapshots__/agg_group.test.tsx.snap | 0 .../public/components/agg.test.tsx | 0 .../public/components/agg.tsx | 3 +- .../public/components/agg_add.tsx | 2 +- .../public/components/agg_common_props.ts | 0 .../public/components/agg_group.test.tsx | 0 .../public/components/agg_group.tsx | 3 +- .../components/agg_group_helper.test.ts | 0 .../public/components/agg_group_helper.tsx | 0 .../public/components/agg_group_state.tsx | 0 .../public/components/agg_param.tsx | 0 .../public/components/agg_param_props.ts | 0 .../public/components/agg_params.test.tsx | 4 +- .../public/components/agg_params.tsx | 4 +- .../components/agg_params_helper.test.ts | 0 .../public/components/agg_params_helper.ts | 2 +- .../public/components/agg_params_map.ts | 7 +- .../public/components/agg_params_state.ts | 0 .../public/components/agg_select.tsx | 2 +- .../extended_bounds.test.tsx.snap | 0 .../__snapshots__/metric_agg.test.tsx.snap | 0 .../controls/__snapshots__/size.test.tsx.snap | 0 .../__snapshots__/top_aggregate.test.tsx.snap | 0 .../components/controls/agg_control_props.tsx | 0 .../components/controls/agg_utils.test.tsx | 0 .../components/controls/auto_precision.tsx | 0 .../controls/components/from_to_list.tsx | 74 ++++++++------- .../controls/components/input_list.tsx | 95 +++++++++++-------- .../controls/components/mask_list.tsx | 72 +++++++------- .../__snapshots__/number_list.test.tsx.snap | 0 .../__snapshots__/number_row.test.tsx.snap | 0 .../controls/components/number_list/index.ts | 0 .../number_list/number_list.test.tsx | 0 .../components/number_list/number_list.tsx | 4 +- .../number_list/number_row.test.tsx | 0 .../components/number_list/number_row.tsx | 0 .../components/number_list/range.test.ts | 1 - .../controls/components/number_list/range.ts | 0 .../components/number_list/utils.test.ts | 0 .../controls/components/number_list/utils.ts | 0 .../components/controls/date_ranges.test.tsx | 4 +- .../components/controls/date_ranges.tsx | 37 +++++--- .../components/controls/drop_partials.tsx | 0 .../controls/extended_bounds.test.tsx | 0 .../components/controls/extended_bounds.tsx | 0 .../public/components/controls/field.test.tsx | 0 .../public/components/controls/field.tsx | 8 +- .../public/components/controls/filter.tsx | 2 +- .../public/components/controls/filters.tsx | 9 +- .../controls/has_extended_bounds.tsx | 19 +++- .../public/components/controls/index.ts | 0 .../components/controls/ip_range_type.tsx | 0 .../public/components/controls/ip_ranges.tsx | 28 ++++-- .../controls/is_filtered_by_collar.tsx | 0 .../components/controls/metric_agg.test.tsx | 0 .../public/components/controls/metric_agg.tsx | 0 .../components/controls/min_doc_count.tsx | 0 .../components/controls/missing_bucket.tsx | 9 +- .../components/controls/number_interval.tsx | 2 +- .../public/components/controls/order.tsx | 2 +- .../components/controls/order_agg.test.tsx | 0 .../public/components/controls/order_agg.tsx | 4 +- .../public/components/controls/order_by.tsx | 10 +- .../components/controls/other_bucket.tsx | 0 .../components/controls/percentile_ranks.tsx | 0 .../components/controls/percentiles.test.tsx | 0 .../components/controls/percentiles.tsx | 0 .../public/components/controls/precision.tsx | 2 +- .../controls/radius_ratio_option.tsx | 7 +- .../components/controls/range_control.tsx | 0 .../public/components/controls/ranges.tsx | 63 ++++++------ .../public/components/controls/raw_json.tsx | 0 .../components/controls/rows_or_columns.tsx | 0 .../components/controls/scale_metrics.tsx | 0 .../public/components/controls/size.test.tsx | 0 .../public/components/controls/size.tsx | 2 +- .../public/components/controls/string.tsx | 2 +- .../public/components/controls/sub_agg.tsx | 5 +- .../public/components/controls/sub_metric.tsx | 9 +- .../public/components/controls/switch.tsx | 0 .../public/components/controls/test_utils.ts | 0 .../components/controls/time_interval.tsx | 4 +- .../controls/top_aggregate.test.tsx | 0 .../components/controls/top_aggregate.tsx | 4 +- .../public/components/controls/top_field.tsx | 0 .../public/components/controls/top_size.tsx | 0 .../components/controls/top_sort_field.tsx | 0 .../components/controls/use_geocentroid.tsx | 0 .../components/controls/utils/agg_utils.ts | 0 .../public/components/controls/utils/index.ts | 0 .../controls/utils/inline_comp_wrapper.tsx | 0 .../strings/comma_separated_list.test.ts | 0 .../utils/strings/comma_separated_list.ts | 0 .../controls/utils/strings/index.ts | 0 .../controls/utils/strings/prose.test.ts | 0 .../controls/utils/strings/prose.ts | 0 .../components/controls/utils/use_handlers.ts | 0 .../public/components/sidebar/controls.tsx | 2 +- .../public/components/sidebar/data_tab.tsx | 4 +- .../public/components/sidebar/index.ts | 0 .../public/components/sidebar/navbar.tsx | 0 .../public/components/sidebar/sidebar.tsx | 7 +- .../components/sidebar/sidebar_title.tsx | 4 +- .../components/sidebar/state/actions.ts | 0 .../components/sidebar/state/constants.ts | 0 .../sidebar/state/editor_form_state.ts | 0 .../public/components/sidebar/state/index.ts | 2 +- .../components/sidebar/state/reducers.ts | 2 +- .../public/components/utils/editor_config.ts | 0 .../public/components/utils/index.ts | 0 .../public/default_editor.tsx | 4 +- .../public/default_editor_controller.tsx | 6 +- .../vis_default_editor/public/editor_size.ts | 0 .../vis_default_editor/public/index.scss | 0 .../vis_default_editor/public/index.ts | 2 + .../vis_default_editor/public/schemas.ts | 2 +- .../vis_default_editor/public/types.ts | 0 .../vis_default_editor/public/utils.test.ts | 0 .../vis_default_editor/public/utils.ts | 0 .../public/vis_options_props.tsx | 0 .../public/vis_type_agg_filter.ts | 2 +- .../self_changing_editor.tsx | 2 +- 176 files changed, 366 insertions(+), 359 deletions(-) delete mode 100644 src/legacy/core_plugins/vis_default_editor/index.ts delete mode 100644 src/legacy/core_plugins/vis_default_editor/package.json create mode 100644 src/plugins/vis_default_editor/README.md rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/_agg.scss (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/_agg_params.scss (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/_default.scss (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/_sidebar.scss (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/__snapshots__/agg.test.tsx.snap (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/__snapshots__/agg_group.test.tsx.snap (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/agg.test.tsx (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/agg.tsx (98%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/agg_add.tsx (98%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/agg_common_props.ts (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/agg_group.test.tsx (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/agg_group.tsx (97%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/agg_group_helper.test.ts (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/agg_group_helper.tsx (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/agg_group_state.tsx (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/agg_param.tsx (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/agg_param_props.ts (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/agg_params.test.tsx (96%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/agg_params.tsx (98%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/agg_params_helper.test.ts (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/agg_params_helper.ts (99%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/agg_params_map.ts (96%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/agg_params_state.ts (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/agg_select.tsx (98%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/__snapshots__/extended_bounds.test.tsx.snap (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/__snapshots__/metric_agg.test.tsx.snap (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/__snapshots__/size.test.tsx.snap (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/__snapshots__/top_aggregate.test.tsx.snap (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/agg_control_props.tsx (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/agg_utils.test.tsx (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/auto_precision.tsx (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/components/from_to_list.tsx (68%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/components/input_list.tsx (75%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/components/mask_list.tsx (62%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/components/number_list/__snapshots__/number_list.test.tsx.snap (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/components/number_list/__snapshots__/number_row.test.tsx.snap (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/components/number_list/index.ts (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/components/number_list/number_list.test.tsx (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/components/number_list/number_list.tsx (98%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/components/number_list/number_row.test.tsx (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/components/number_list/number_row.tsx (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/components/number_list/range.test.ts (98%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/components/number_list/range.ts (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/components/number_list/utils.test.ts (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/components/number_list/utils.ts (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/date_ranges.test.tsx (95%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/date_ranges.tsx (90%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/drop_partials.tsx (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/extended_bounds.test.tsx (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/extended_bounds.tsx (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/field.test.tsx (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/field.tsx (97%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/filter.tsx (99%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/filters.tsx (96%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/has_extended_bounds.tsx (73%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/index.ts (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/ip_range_type.tsx (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/ip_ranges.tsx (79%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/is_filtered_by_collar.tsx (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/metric_agg.test.tsx (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/metric_agg.tsx (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/min_doc_count.tsx (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/missing_bucket.tsx (93%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/number_interval.tsx (99%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/order.tsx (98%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/order_agg.test.tsx (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/order_agg.tsx (97%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/order_by.tsx (94%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/other_bucket.tsx (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/percentile_ranks.tsx (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/percentiles.test.tsx (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/percentiles.tsx (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/precision.tsx (95%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/radius_ratio_option.tsx (95%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/range_control.tsx (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/ranges.tsx (91%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/raw_json.tsx (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/rows_or_columns.tsx (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/scale_metrics.tsx (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/size.test.tsx (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/size.tsx (98%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/string.tsx (98%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/sub_agg.tsx (97%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/sub_metric.tsx (96%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/switch.tsx (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/test_utils.ts (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/time_interval.tsx (98%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/top_aggregate.test.tsx (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/top_aggregate.tsx (97%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/top_field.tsx (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/top_size.tsx (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/top_sort_field.tsx (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/use_geocentroid.tsx (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/utils/agg_utils.ts (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/utils/index.ts (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/utils/inline_comp_wrapper.tsx (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/utils/strings/comma_separated_list.test.ts (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/utils/strings/comma_separated_list.ts (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/utils/strings/index.ts (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/utils/strings/prose.test.ts (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/utils/strings/prose.ts (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/controls/utils/use_handlers.ts (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/sidebar/controls.tsx (98%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/sidebar/data_tab.tsx (97%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/sidebar/index.ts (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/sidebar/navbar.tsx (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/sidebar/sidebar.tsx (96%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/sidebar/sidebar_title.tsx (97%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/sidebar/state/actions.ts (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/sidebar/state/constants.ts (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/sidebar/state/editor_form_state.ts (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/sidebar/state/index.ts (96%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/sidebar/state/reducers.ts (99%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/utils/editor_config.ts (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/components/utils/index.ts (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/default_editor.tsx (94%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/default_editor_controller.tsx (92%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/editor_size.ts (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/index.scss (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/index.ts (97%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/schemas.ts (96%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/types.ts (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/utils.test.ts (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/utils.ts (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/vis_options_props.tsx (100%) rename src/{legacy/core_plugins => plugins}/vis_default_editor/public/vis_type_agg_filter.ts (97%) diff --git a/.eslintrc.js b/.eslintrc.js index 3c173e5244009..2ce6d279d93a9 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -69,26 +69,6 @@ module.exports = { 'jsx-a11y/no-onchange': 'off', }, }, - { - files: ['src/legacy/core_plugins/expressions/**/*.{js,ts,tsx}'], - rules: { - 'react-hooks/exhaustive-deps': 'off', - }, - }, - { - files: [ - 'src/legacy/core_plugins/vis_default_editor/public/components/controls/**/*.{ts,tsx}', - ], - rules: { - 'react-hooks/exhaustive-deps': 'off', - }, - }, - { - files: ['src/legacy/ui/public/vis/**/*.{js,ts,tsx}'], - rules: { - 'react-hooks/exhaustive-deps': 'off', - }, - }, { files: ['src/plugins/es_ui_shared/**/*.{js,ts,tsx}'], rules: { diff --git a/.i18nrc.json b/.i18nrc.json index c293b3103a39c..3b0b40b40792e 100644 --- a/.i18nrc.json +++ b/.i18nrc.json @@ -43,7 +43,7 @@ "tileMap": "src/legacy/core_plugins/tile_map", "timelion": ["src/legacy/core_plugins/timelion", "src/legacy/core_plugins/vis_type_timelion", "src/plugins/timelion"], "uiActions": "src/plugins/ui_actions", - "visDefaultEditor": "src/legacy/core_plugins/vis_default_editor", + "visDefaultEditor": "src/plugins/vis_default_editor", "visTypeMarkdown": "src/legacy/core_plugins/vis_type_markdown", "visTypeMetric": "src/legacy/core_plugins/vis_type_metric", "visTypeTable": "src/legacy/core_plugins/vis_type_table", diff --git a/src/legacy/core_plugins/input_control_vis/public/components/editor/controls_tab.tsx b/src/legacy/core_plugins/input_control_vis/public/components/editor/controls_tab.tsx index 029e1f149d052..b7114f1029ef2 100644 --- a/src/legacy/core_plugins/input_control_vis/public/components/editor/controls_tab.tsx +++ b/src/legacy/core_plugins/input_control_vis/public/components/editor/controls_tab.tsx @@ -30,7 +30,7 @@ import { EuiSelect, } from '@elastic/eui'; -import { VisOptionsProps } from 'src/legacy/core_plugins/vis_default_editor/public'; +import { VisOptionsProps } from 'src/plugins/vis_default_editor/public'; import { IIndexPattern } from 'src/plugins/data/public'; import { ControlEditor } from './control_editor'; import { diff --git a/src/legacy/core_plugins/input_control_vis/public/components/editor/options_tab.tsx b/src/legacy/core_plugins/input_control_vis/public/components/editor/options_tab.tsx index 95b14619c3416..cdff6cabad8ba 100644 --- a/src/legacy/core_plugins/input_control_vis/public/components/editor/options_tab.tsx +++ b/src/legacy/core_plugins/input_control_vis/public/components/editor/options_tab.tsx @@ -23,7 +23,7 @@ import { EuiForm, EuiFormRow, EuiSwitch } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiSwitchEvent } from '@elastic/eui'; -import { VisOptionsProps } from 'src/legacy/core_plugins/vis_default_editor/public'; +import { VisOptionsProps } from 'src/plugins/vis_default_editor/public'; interface OptionsTabParams { updateFiltersOnChange: boolean; diff --git a/src/legacy/core_plugins/kibana/public/visualize/_index.scss b/src/legacy/core_plugins/kibana/public/visualize/_index.scss index 0632831578bd0..079d82936bb57 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/_index.scss +++ b/src/legacy/core_plugins/kibana/public/visualize/_index.scss @@ -1,2 +1,5 @@ // Visualize plugin styles @import 'np_ready/index'; + +// should be removed while moving the visualize into NP +@import '../../../../../plugins/vis_default_editor/public/index' 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 addc608efd57d..d5440c4677d8a 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/kibana_services.ts +++ b/src/legacy/core_plugins/kibana/public/visualize/kibana_services.ts @@ -36,7 +36,7 @@ import { VisualizationsStart } from '../../../../../plugins/visualizations/publi import { SavedVisualizations } from './np_ready/types'; import { UsageCollectionSetup } from '../../../../../plugins/usage_collection/public'; import { KibanaLegacyStart } from '../../../../../plugins/kibana_legacy/public'; -import { DefaultEditorController } from '../../../vis_default_editor/public'; +import { DefaultEditorController } from '../../../../../plugins/vis_default_editor/public'; export interface VisualizeKibanaServices { pluginInitializerContext: PluginInitializerContext; diff --git a/src/legacy/core_plugins/kibana/public/visualize/plugin.ts b/src/legacy/core_plugins/kibana/public/visualize/plugin.ts index 81d8458010f19..4ffbc307c69a8 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/plugin.ts +++ b/src/legacy/core_plugins/kibana/public/visualize/plugin.ts @@ -51,7 +51,7 @@ import { HomePublicPluginSetup, } from '../../../../../plugins/home/public'; import { UsageCollectionSetup } from '../../../../../plugins/usage_collection/public'; -import { DefaultEditorController } from '../../../vis_default_editor/public'; +import { DefaultEditorController } from '../../../../../plugins/vis_default_editor/public'; export interface VisualizePluginStartDependencies { data: DataPublicPluginStart; 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 4219e2e715150..61cfbf00ded9e 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 @@ -23,7 +23,7 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import { FileLayerField, VectorLayer, ServiceSettings } from 'ui/vis/map/service_settings'; -import { VisOptionsProps } from 'src/legacy/core_plugins/vis_default_editor/public'; +import { VisOptionsProps } from 'src/plugins/vis_default_editor/public'; import { NumberInputOption, SelectOption, SwitchOption } from '../../../vis_type_vislib/public'; import { WmsOptions } from '../../../tile_map/public/components/wms_options'; import { RegionMapVisParams } from '../types'; diff --git a/src/legacy/core_plugins/region_map/public/region_map_type.js b/src/legacy/core_plugins/region_map/public/region_map_type.js index 4faa3f92abb5a..9174b03cf843c 100644 --- a/src/legacy/core_plugins/region_map/public/region_map_type.js +++ b/src/legacy/core_plugins/region_map/public/region_map_type.js @@ -22,7 +22,7 @@ import { mapToLayerWithId } from './util'; import { createRegionMapVisualization } from './region_map_visualization'; import { RegionMapOptions } from './components/region_map_options'; import { truncatedColorSchemas } from '../../../../plugins/charts/public'; -import { Schemas } from '../../vis_default_editor/public'; +import { Schemas } from '../../../../plugins/vis_default_editor/public'; // TODO: reference to TILE_MAP plugin should be removed import { ORIGIN } from '../../tile_map/common/origin'; diff --git a/src/legacy/core_plugins/tile_map/public/components/tile_map_options.tsx b/src/legacy/core_plugins/tile_map/public/components/tile_map_options.tsx index 168f56b771b7e..9169647aa2aef 100644 --- a/src/legacy/core_plugins/tile_map/public/components/tile_map_options.tsx +++ b/src/legacy/core_plugins/tile_map/public/components/tile_map_options.tsx @@ -21,7 +21,7 @@ import React, { useEffect } from 'react'; import { EuiPanel, EuiSpacer } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { VisOptionsProps } from 'src/legacy/core_plugins/vis_default_editor/public'; +import { VisOptionsProps } from 'src/plugins/vis_default_editor/public'; import { BasicOptions, RangeOption, diff --git a/src/legacy/core_plugins/tile_map/public/tile_map_type.js b/src/legacy/core_plugins/tile_map/public/tile_map_type.js index 39d39a4c8f8fc..fe82ad5c7352b 100644 --- a/src/legacy/core_plugins/tile_map/public/tile_map_type.js +++ b/src/legacy/core_plugins/tile_map/public/tile_map_type.js @@ -22,7 +22,7 @@ import { i18n } from '@kbn/i18n'; import { convertToGeoJson } from 'ui/vis/map/convert_to_geojson'; -import { Schemas } from '../../vis_default_editor/public'; +import { Schemas } from '../../../../plugins/vis_default_editor/public'; import { createTileMapVisualization } from './tile_map_visualization'; import { TileMapOptions } from './components/tile_map_options'; import { MapTypes } from './map_types'; diff --git a/src/legacy/core_plugins/vis_default_editor/index.ts b/src/legacy/core_plugins/vis_default_editor/index.ts deleted file mode 100644 index ee7b5ee4a62ff..0000000000000 --- a/src/legacy/core_plugins/vis_default_editor/index.ts +++ /dev/null @@ -1,42 +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 { resolve } from 'path'; -import { Legacy } from 'kibana'; - -import { LegacyPluginApi, LegacyPluginInitializer } from '../../../../src/legacy/types'; - -const vidDefaultEditorPluginInitializer: LegacyPluginInitializer = ({ Plugin }: LegacyPluginApi) => - new Plugin({ - id: 'vis_default_editor', - require: [], - publicDir: resolve(__dirname, 'public'), - uiExports: { - styleSheetPaths: resolve(__dirname, 'public/index.scss'), - }, - init: (server: Legacy.Server) => ({}), - config(Joi: any) { - return Joi.object({ - enabled: Joi.boolean().default(true), - }).default(); - }, - } as Legacy.PluginSpecOptions); - -// eslint-disable-next-line import/no-default-export -export default vidDefaultEditorPluginInitializer; diff --git a/src/legacy/core_plugins/vis_default_editor/package.json b/src/legacy/core_plugins/vis_default_editor/package.json deleted file mode 100644 index 77dcaff41da6b..0000000000000 --- a/src/legacy/core_plugins/vis_default_editor/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "vis_default_editor", - "version": "kibana" -} diff --git a/src/legacy/core_plugins/vis_type_markdown/public/markdown_options.tsx b/src/legacy/core_plugins/vis_type_markdown/public/markdown_options.tsx index 8a4297d3b8149..a6349793619a0 100644 --- a/src/legacy/core_plugins/vis_type_markdown/public/markdown_options.tsx +++ b/src/legacy/core_plugins/vis_type_markdown/public/markdown_options.tsx @@ -30,7 +30,7 @@ import { } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -import { VisOptionsProps } from 'src/legacy/core_plugins/vis_default_editor/public'; +import { VisOptionsProps } from 'src/plugins/vis_default_editor/public'; import { MarkdownVisParams } from './types'; function MarkdownOptions({ stateParams, setValue }: VisOptionsProps) { diff --git a/src/legacy/core_plugins/vis_type_markdown/public/markdown_vis.ts b/src/legacy/core_plugins/vis_type_markdown/public/markdown_vis.ts index b84d9638eb973..57ea6d9c9bb3d 100644 --- a/src/legacy/core_plugins/vis_type_markdown/public/markdown_vis.ts +++ b/src/legacy/core_plugins/vis_type_markdown/public/markdown_vis.ts @@ -22,7 +22,7 @@ import { i18n } from '@kbn/i18n'; import { MarkdownVisWrapper } from './markdown_vis_controller'; import { MarkdownOptions } from './markdown_options'; import { SettingsOptions } from './settings_options'; -import { DefaultEditorSize } from '../../vis_default_editor/public'; +import { DefaultEditorSize } from '../../../../plugins/vis_default_editor/public'; export const markdownVisDefinition = { name: 'markdown', diff --git a/src/legacy/core_plugins/vis_type_markdown/public/settings_options.tsx b/src/legacy/core_plugins/vis_type_markdown/public/settings_options.tsx index ac1d4bcc82cec..552fd63373554 100644 --- a/src/legacy/core_plugins/vis_type_markdown/public/settings_options.tsx +++ b/src/legacy/core_plugins/vis_type_markdown/public/settings_options.tsx @@ -21,7 +21,7 @@ import React from 'react'; import { EuiPanel } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { VisOptionsProps } from 'src/legacy/core_plugins/vis_default_editor/public'; +import { VisOptionsProps } from 'src/plugins/vis_default_editor/public'; import { RangeOption, SwitchOption } from '../../vis_type_vislib/public'; import { MarkdownVisParams } from './types'; diff --git a/src/legacy/core_plugins/vis_type_metric/public/components/metric_vis_options.tsx b/src/legacy/core_plugins/vis_type_metric/public/components/metric_vis_options.tsx index 661f16d6497ba..5c3032511f09a 100644 --- a/src/legacy/core_plugins/vis_type_metric/public/components/metric_vis_options.tsx +++ b/src/legacy/core_plugins/vis_type_metric/public/components/metric_vis_options.tsx @@ -29,7 +29,7 @@ import { import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import { VisOptionsProps } from 'src/legacy/core_plugins/vis_default_editor/public'; +import { VisOptionsProps } from 'src/plugins/vis_default_editor/public'; import { ColorModes, ColorRanges, diff --git a/src/legacy/core_plugins/vis_type_metric/public/metric_vis_fn.test.ts b/src/legacy/core_plugins/vis_type_metric/public/metric_vis_fn.test.ts index 22c32895d6803..4094cd4eff060 100644 --- a/src/legacy/core_plugins/vis_type_metric/public/metric_vis_fn.test.ts +++ b/src/legacy/core_plugins/vis_type_metric/public/metric_vis_fn.test.ts @@ -23,10 +23,6 @@ import { functionWrapper } from '../../../../plugins/expressions/common/expressi jest.mock('ui/new_platform'); -jest.mock('../../vis_default_editor/public', () => ({ - Schemas: class {}, -})); - describe('interpreter/functions#metric', () => { const fn = functionWrapper(createMetricVisFn()); const context = { diff --git a/src/legacy/core_plugins/vis_type_metric/public/metric_vis_type.test.ts b/src/legacy/core_plugins/vis_type_metric/public/metric_vis_type.test.ts index 459da47556307..706693eff1007 100644 --- a/src/legacy/core_plugins/vis_type_metric/public/metric_vis_type.test.ts +++ b/src/legacy/core_plugins/vis_type_metric/public/metric_vis_type.test.ts @@ -22,10 +22,6 @@ import { MetricVisComponent } from './components/metric_vis_component'; jest.mock('ui/new_platform'); -jest.mock('../../vis_default_editor/public', () => ({ - Schemas: class {}, -})); - describe('metric_vis - createMetricVisTypeDefinition', () => { it('has metric vis component set', () => { const def = createMetricVisTypeDefinition(); diff --git a/src/legacy/core_plugins/vis_type_metric/public/metric_vis_type.ts b/src/legacy/core_plugins/vis_type_metric/public/metric_vis_type.ts index f29164f7e540d..3bbb8964122e5 100644 --- a/src/legacy/core_plugins/vis_type_metric/public/metric_vis_type.ts +++ b/src/legacy/core_plugins/vis_type_metric/public/metric_vis_type.ts @@ -24,7 +24,7 @@ import { MetricVisOptions } from './components/metric_vis_options'; import { ColorModes } from '../../vis_type_vislib/public'; import { ColorSchemas, colorSchemas } from '../../../../plugins/charts/public'; import { AggGroupNames } from '../../../../plugins/data/public'; -import { Schemas } from '../../vis_default_editor/public'; +import { Schemas } from '../../../../plugins/vis_default_editor/public'; export const createMetricVisTypeDefinition = () => ({ name: 'metric', diff --git a/src/legacy/core_plugins/vis_type_table/public/components/table_vis_options.tsx b/src/legacy/core_plugins/vis_type_table/public/components/table_vis_options.tsx index 30a9526273166..d01ab31e0a843 100644 --- a/src/legacy/core_plugins/vis_type_table/public/components/table_vis_options.tsx +++ b/src/legacy/core_plugins/vis_type_table/public/components/table_vis_options.tsx @@ -23,7 +23,7 @@ import { EuiIconTip, EuiPanel } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import { VisOptionsProps } from 'src/legacy/core_plugins/vis_default_editor/public'; +import { VisOptionsProps } from 'src/plugins/vis_default_editor/public'; import { search } from '../../../../../plugins/data/public'; import { NumberInputOption, SwitchOption, SelectOption } from '../../../vis_type_vislib/public'; import { TableVisParams } from '../types'; diff --git a/src/legacy/core_plugins/vis_type_table/public/table_vis_type.ts b/src/legacy/core_plugins/vis_type_table/public/table_vis_type.ts index d26e860e51272..43816121bc23b 100644 --- a/src/legacy/core_plugins/vis_type_table/public/table_vis_type.ts +++ b/src/legacy/core_plugins/vis_type_table/public/table_vis_type.ts @@ -19,7 +19,7 @@ import { i18n } from '@kbn/i18n'; import { AggGroupNames } from '../../../../plugins/data/public'; -import { Schemas } from '../../vis_default_editor/public'; +import { Schemas } from '../../../../plugins/vis_default_editor/public'; import { Vis } from '../../../../plugins/visualizations/public'; import { tableVisResponseHandler } from './table_vis_response_handler'; // @ts-ignore diff --git a/src/legacy/core_plugins/vis_type_tagcloud/public/components/tag_cloud_options.tsx b/src/legacy/core_plugins/vis_type_tagcloud/public/components/tag_cloud_options.tsx index a9e816f70cf53..80e4e1de7ddab 100644 --- a/src/legacy/core_plugins/vis_type_tagcloud/public/components/tag_cloud_options.tsx +++ b/src/legacy/core_plugins/vis_type_tagcloud/public/components/tag_cloud_options.tsx @@ -20,8 +20,8 @@ import React from 'react'; import { EuiPanel } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import { VisOptionsProps } from 'src/plugins/vis_default_editor/public'; import { ValidatedDualRange } from '../../../../../../src/plugins/kibana_react/public'; -import { VisOptionsProps } from '../../../vis_default_editor/public'; import { SelectOption, SwitchOption } from '../../../vis_type_vislib/public'; import { TagCloudVisParams } from '../types'; diff --git a/src/legacy/core_plugins/vis_type_tagcloud/public/tag_cloud_type.ts b/src/legacy/core_plugins/vis_type_tagcloud/public/tag_cloud_type.ts index 5a8cc3004a315..b7dfa62c93fb9 100644 --- a/src/legacy/core_plugins/vis_type_tagcloud/public/tag_cloud_type.ts +++ b/src/legacy/core_plugins/vis_type_tagcloud/public/tag_cloud_type.ts @@ -19,7 +19,7 @@ import { i18n } from '@kbn/i18n'; -import { Schemas } from '../../vis_default_editor/public'; +import { Schemas } from '../../../../plugins/vis_default_editor/public'; import { TagCloudOptions } from './components/tag_cloud_options'; diff --git a/src/legacy/core_plugins/vis_type_timelion/public/components/timelion_interval.tsx b/src/legacy/core_plugins/vis_type_timelion/public/components/timelion_interval.tsx index 6e29b111d422a..8a8e1b22fb78d 100644 --- a/src/legacy/core_plugins/vis_type_timelion/public/components/timelion_interval.tsx +++ b/src/legacy/core_plugins/vis_type_timelion/public/components/timelion_interval.tsx @@ -23,7 +23,7 @@ import { i18n } from '@kbn/i18n'; import { search } from '../../../../../plugins/data/public'; const { isValidEsInterval } = search.aggs; -import { useValidation } from '../../../vis_default_editor/public'; +import { useValidation } from '../../../../../plugins/vis_default_editor/public'; const intervalOptions = [ { diff --git a/src/legacy/core_plugins/vis_type_timelion/public/timelion_options.tsx b/src/legacy/core_plugins/vis_type_timelion/public/timelion_options.tsx index b7c40e15c11fd..afffcf7ccaf7a 100644 --- a/src/legacy/core_plugins/vis_type_timelion/public/timelion_options.tsx +++ b/src/legacy/core_plugins/vis_type_timelion/public/timelion_options.tsx @@ -20,9 +20,9 @@ import React, { useCallback } from 'react'; import { EuiPanel } from '@elastic/eui'; +import { VisOptionsProps } from 'src/plugins/vis_default_editor/public'; import { VisParams } from './timelion_vis_fn'; import { TimelionInterval, TimelionExpressionInput } from './components'; -import { VisOptionsProps } from '../../vis_default_editor/public'; function TimelionOptions({ stateParams, setValue, setValidity }: VisOptionsProps) { const setInterval = useCallback((value: VisParams['interval']) => setValue('interval', value), [ diff --git a/src/legacy/core_plugins/vis_type_timelion/public/timelion_vis_type.tsx b/src/legacy/core_plugins/vis_type_timelion/public/timelion_vis_type.tsx index 6679553004097..5be77b3e51a6a 100644 --- a/src/legacy/core_plugins/vis_type_timelion/public/timelion_vis_type.tsx +++ b/src/legacy/core_plugins/vis_type_timelion/public/timelion_vis_type.tsx @@ -21,7 +21,7 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import { KibanaContextProvider } from '../../../../plugins/kibana_react/public'; -import { DefaultEditorSize } from '../../vis_default_editor/public'; +import { DefaultEditorSize } from '../../../../plugins/vis_default_editor/public'; import { getTimelionRequestHandler } from './helpers/timelion_request_handler'; import { TimelionVisComponent, TimelionVisComponentProp } from './components'; import { TimelionOptions } from './timelion_options'; diff --git a/src/legacy/core_plugins/vis_type_vega/public/components/vega_vis_editor.tsx b/src/legacy/core_plugins/vis_type_vega/public/components/vega_vis_editor.tsx index 707a6830b5ba4..31144065d7b40 100644 --- a/src/legacy/core_plugins/vis_type_vega/public/components/vega_vis_editor.tsx +++ b/src/legacy/core_plugins/vis_type_vega/public/components/vega_vis_editor.tsx @@ -24,11 +24,11 @@ import compactStringify from 'json-stringify-pretty-compact'; import hjson from 'hjson'; import { i18n } from '@kbn/i18n'; +import { VisOptionsProps } from 'src/plugins/vis_default_editor/public'; import { getNotifications } from '../services'; import { VisParams } from '../vega_fn'; import { VegaHelpMenu } from './vega_help_menu'; import { VegaActionsMenu } from './vega_actions_menu'; -import { VisOptionsProps } from '../../../vis_default_editor/public'; const aceOptions = { maxLines: Infinity, diff --git a/src/legacy/core_plugins/vis_type_vega/public/vega_type.ts b/src/legacy/core_plugins/vis_type_vega/public/vega_type.ts index b0ec90d2c378f..5d9ed5c8df91c 100644 --- a/src/legacy/core_plugins/vis_type_vega/public/vega_type.ts +++ b/src/legacy/core_plugins/vis_type_vega/public/vega_type.ts @@ -18,8 +18,7 @@ */ import { i18n } from '@kbn/i18n'; -// @ts-ignore -import { DefaultEditorSize } from '../../vis_default_editor/public'; +import { DefaultEditorSize } from '../../../../plugins/vis_default_editor/public'; import { VegaVisualizationDependencies } from './plugin'; import { VegaVisEditor } from './components'; import { defaultFeedbackMessage } from '../../../../plugins/kibana_utils/common'; diff --git a/src/legacy/core_plugins/vis_type_vislib/public/area.ts b/src/legacy/core_plugins/vis_type_vislib/public/area.ts index e79555470298b..68decacaaa040 100644 --- a/src/legacy/core_plugins/vis_type_vislib/public/area.ts +++ b/src/legacy/core_plugins/vis_type_vislib/public/area.ts @@ -24,7 +24,7 @@ import { palettes } from '@elastic/eui/lib/services'; import { euiPaletteColorBlind } from '@elastic/eui/lib/services'; import { AggGroupNames } from '../../../../plugins/data/public'; -import { Schemas } from '../../vis_default_editor/public'; +import { Schemas } from '../../../../plugins/vis_default_editor/public'; import { Positions, ChartTypes, diff --git a/src/legacy/core_plugins/vis_type_vislib/public/components/common/basic_options.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/common/basic_options.tsx index 1138f66d21cfa..baf3e8ecd1b28 100644 --- a/src/legacy/core_plugins/vis_type_vislib/public/components/common/basic_options.tsx +++ b/src/legacy/core_plugins/vis_type_vislib/public/components/common/basic_options.tsx @@ -20,7 +20,7 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; -import { VisOptionsProps } from '../../../../vis_default_editor/public'; +import { VisOptionsProps } from 'src/plugins/vis_default_editor/public'; import { SwitchOption } from './switch'; import { SelectOption } from './select'; diff --git a/src/legacy/core_plugins/vis_type_vislib/public/components/common/color_ranges.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/common/color_ranges.tsx index 2c9b1b543e8c2..84c70f10b12da 100644 --- a/src/legacy/core_plugins/vis_type_vislib/public/components/common/color_ranges.tsx +++ b/src/legacy/core_plugins/vis_type_vislib/public/components/common/color_ranges.tsx @@ -22,7 +22,10 @@ import { last } from 'lodash'; import { i18n } from '@kbn/i18n'; -import { RangeValues, RangesParamEditor } from '../../../../vis_default_editor/public'; +import { + RangeValues, + RangesParamEditor, +} from '../../../../../../plugins/vis_default_editor/public'; export type SetColorRangeValue = (paramName: string, value: RangeValues[]) => void; diff --git a/src/legacy/core_plugins/vis_type_vislib/public/components/common/color_schema.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/common/color_schema.tsx index 06ce0a2b4af64..35d7f7b13235e 100644 --- a/src/legacy/core_plugins/vis_type_vislib/public/components/common/color_schema.tsx +++ b/src/legacy/core_plugins/vis_type_vislib/public/components/common/color_schema.tsx @@ -22,7 +22,7 @@ import { i18n } from '@kbn/i18n'; import { EuiLink, EuiText } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -import { VisOptionsProps } from '../../../../vis_default_editor/public'; +import { VisOptionsProps } from 'src/plugins/vis_default_editor/public'; import { SelectOption } from './select'; import { SwitchOption } from './switch'; import { ColorSchemaVislibParams } from '../../types'; diff --git a/src/legacy/core_plugins/vis_type_vislib/public/components/common/validation_wrapper.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/common/validation_wrapper.tsx index c069d4c935669..718056fd85492 100644 --- a/src/legacy/core_plugins/vis_type_vislib/public/components/common/validation_wrapper.tsx +++ b/src/legacy/core_plugins/vis_type_vislib/public/components/common/validation_wrapper.tsx @@ -19,7 +19,7 @@ import React, { useEffect, useState, useCallback } from 'react'; -import { VisOptionsProps } from '../../../../vis_default_editor/public'; +import { VisOptionsProps } from 'src/plugins/vis_default_editor/public'; export interface ValidationVisOptionsProps extends VisOptionsProps { setMultipleValidity(paramName: string, isValid: boolean): void; diff --git a/src/legacy/core_plugins/vis_type_vislib/public/components/options/gauge/index.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/options/gauge/index.tsx index 706035a7b814e..6109b548f9412 100644 --- a/src/legacy/core_plugins/vis_type_vislib/public/components/options/gauge/index.tsx +++ b/src/legacy/core_plugins/vis_type_vislib/public/components/options/gauge/index.tsx @@ -20,7 +20,7 @@ import React, { useCallback } from 'react'; import { EuiSpacer } from '@elastic/eui'; -import { VisOptionsProps } from '../../../../../vis_default_editor/public'; +import { VisOptionsProps } from 'src/plugins/vis_default_editor/public'; import { GaugeVisParams } from '../../../gauge'; import { RangesPanel } from './ranges_panel'; import { StylePanel } from './style_panel'; diff --git a/src/legacy/core_plugins/vis_type_vislib/public/components/options/heatmap/index.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/options/heatmap/index.tsx index 452b9ed9bdbb1..715b5902b69da 100644 --- a/src/legacy/core_plugins/vis_type_vislib/public/components/options/heatmap/index.tsx +++ b/src/legacy/core_plugins/vis_type_vislib/public/components/options/heatmap/index.tsx @@ -23,7 +23,7 @@ import { EuiPanel, EuiSpacer, EuiTitle } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import { VisOptionsProps } from '../../../../../vis_default_editor/public'; +import { VisOptionsProps } from 'src/plugins/vis_default_editor/public'; import { BasicOptions, ColorRanges, diff --git a/src/legacy/core_plugins/vis_type_vislib/public/components/options/heatmap/labels_panel.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/options/heatmap/labels_panel.tsx index c74f0ef765c8d..38811bd836459 100644 --- a/src/legacy/core_plugins/vis_type_vislib/public/components/options/heatmap/labels_panel.tsx +++ b/src/legacy/core_plugins/vis_type_vislib/public/components/options/heatmap/labels_panel.tsx @@ -23,7 +23,7 @@ import { EuiColorPicker, EuiFormRow, EuiPanel, EuiSpacer, EuiTitle } from '@elas import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import { VisOptionsProps } from '../../../../../vis_default_editor/public'; +import { VisOptionsProps } from 'src/plugins/vis_default_editor/public'; import { ValueAxis } from '../../../types'; import { HeatmapVisParams } from '../../../heatmap'; import { SwitchOption } from '../../common'; diff --git a/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/category_axis_panel.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/category_axis_panel.tsx index 049df0cdd77be..915885388640c 100644 --- a/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/category_axis_panel.tsx +++ b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/category_axis_panel.tsx @@ -23,7 +23,7 @@ import { EuiPanel, EuiTitle, EuiSpacer } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import { VisOptionsProps } from 'src/legacy/core_plugins/vis_default_editor/public'; +import { VisOptionsProps } from 'src/plugins/vis_default_editor/public'; import { Axis } from '../../../types'; import { SelectOption, SwitchOption } from '../../common'; import { LabelOptions, SetAxisLabel } from './label_options'; diff --git a/src/legacy/core_plugins/vis_type_vislib/public/components/options/pie.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/options/pie.tsx index 2182edafb3ebf..4c0be456aad64 100644 --- a/src/legacy/core_plugins/vis_type_vislib/public/components/options/pie.tsx +++ b/src/legacy/core_plugins/vis_type_vislib/public/components/options/pie.tsx @@ -22,7 +22,7 @@ import { EuiPanel, EuiTitle, EuiSpacer } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import { VisOptionsProps } from '../../../../vis_default_editor/public'; +import { VisOptionsProps } from 'src/plugins/vis_default_editor/public'; import { BasicOptions, TruncateLabelsOption, SwitchOption } from '../common'; import { PieVisParams } from '../../pie'; diff --git a/src/legacy/core_plugins/vis_type_vislib/public/components/options/point_series/grid_panel.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/options/point_series/grid_panel.tsx index db9acafac305c..bb2b3f8fddb49 100644 --- a/src/legacy/core_plugins/vis_type_vislib/public/components/options/point_series/grid_panel.tsx +++ b/src/legacy/core_plugins/vis_type_vislib/public/components/options/point_series/grid_panel.tsx @@ -22,7 +22,7 @@ import { EuiPanel, EuiTitle, EuiSpacer } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import { VisOptionsProps } from '../../../../../vis_default_editor/public'; +import { VisOptionsProps } from 'src/plugins/vis_default_editor/public'; import { SelectOption, SwitchOption } from '../../common'; import { BasicVislibParams, ValueAxis } from '../../../types'; diff --git a/src/legacy/core_plugins/vis_type_vislib/public/gauge.ts b/src/legacy/core_plugins/vis_type_vislib/public/gauge.ts index 4610bd37db5f1..7ad821dbf2f30 100644 --- a/src/legacy/core_plugins/vis_type_vislib/public/gauge.ts +++ b/src/legacy/core_plugins/vis_type_vislib/public/gauge.ts @@ -19,7 +19,7 @@ import { i18n } from '@kbn/i18n'; -import { RangeValues, Schemas } from '../../vis_default_editor/public'; +import { RangeValues, Schemas } from '../../../../plugins/vis_default_editor/public'; import { AggGroupNames } from '../../../../plugins/data/public'; import { GaugeOptions } from './components/options'; import { getGaugeCollections, Alignments, ColorModes, GaugeTypes } from './utils/collections'; diff --git a/src/legacy/core_plugins/vis_type_vislib/public/goal.ts b/src/legacy/core_plugins/vis_type_vislib/public/goal.ts index c918128d01f11..6c311bebe0717 100644 --- a/src/legacy/core_plugins/vis_type_vislib/public/goal.ts +++ b/src/legacy/core_plugins/vis_type_vislib/public/goal.ts @@ -25,7 +25,7 @@ import { createVislibVisController } from './vis_controller'; import { VisTypeVislibDependencies } from './plugin'; import { ColorSchemas } from '../../../../plugins/charts/public'; import { AggGroupNames } from '../../../../plugins/data/public'; -import { Schemas } from '../../vis_default_editor/public'; +import { Schemas } from '../../../../plugins/vis_default_editor/public'; export const createGoalVisTypeDefinition = (deps: VisTypeVislibDependencies) => ({ name: 'goal', diff --git a/src/legacy/core_plugins/vis_type_vislib/public/heatmap.ts b/src/legacy/core_plugins/vis_type_vislib/public/heatmap.ts index 39a583f3c9641..88b4f0fcaf87e 100644 --- a/src/legacy/core_plugins/vis_type_vislib/public/heatmap.ts +++ b/src/legacy/core_plugins/vis_type_vislib/public/heatmap.ts @@ -19,7 +19,7 @@ import { i18n } from '@kbn/i18n'; -import { RangeValues, Schemas } from '../../vis_default_editor/public'; +import { RangeValues, Schemas } from '../../../../plugins/vis_default_editor/public'; import { AggGroupNames } from '../../../../plugins/data/public'; import { AxisTypes, getHeatmapCollections, Positions, ScaleTypes } from './utils/collections'; import { HeatmapOptions } from './components/options'; diff --git a/src/legacy/core_plugins/vis_type_vislib/public/histogram.ts b/src/legacy/core_plugins/vis_type_vislib/public/histogram.ts index 15ef369e5150e..54ec8f98203e2 100644 --- a/src/legacy/core_plugins/vis_type_vislib/public/histogram.ts +++ b/src/legacy/core_plugins/vis_type_vislib/public/histogram.ts @@ -24,7 +24,7 @@ import { palettes } from '@elastic/eui/lib/services'; import { euiPaletteColorBlind } from '@elastic/eui/lib/services'; import { AggGroupNames } from '../../../../plugins/data/public'; -import { Schemas } from '../../vis_default_editor/public'; +import { Schemas } from '../../../../plugins/vis_default_editor/public'; import { Positions, ChartTypes, diff --git a/src/legacy/core_plugins/vis_type_vislib/public/horizontal_bar.ts b/src/legacy/core_plugins/vis_type_vislib/public/horizontal_bar.ts index 8b5811628855c..dc47252ccd44f 100644 --- a/src/legacy/core_plugins/vis_type_vislib/public/horizontal_bar.ts +++ b/src/legacy/core_plugins/vis_type_vislib/public/horizontal_bar.ts @@ -24,7 +24,7 @@ import { palettes } from '@elastic/eui/lib/services'; import { euiPaletteColorBlind } from '@elastic/eui/lib/services'; import { AggGroupNames } from '../../../../plugins/data/public'; -import { Schemas } from '../../vis_default_editor/public'; +import { Schemas } from '../../../../plugins/vis_default_editor/public'; import { Positions, ChartTypes, diff --git a/src/legacy/core_plugins/vis_type_vislib/public/line.ts b/src/legacy/core_plugins/vis_type_vislib/public/line.ts index ac4cda869fe29..885ab295d11e1 100644 --- a/src/legacy/core_plugins/vis_type_vislib/public/line.ts +++ b/src/legacy/core_plugins/vis_type_vislib/public/line.ts @@ -24,7 +24,7 @@ import { palettes } from '@elastic/eui/lib/services'; import { euiPaletteColorBlind } from '@elastic/eui/lib/services'; import { AggGroupNames } from '../../../../plugins/data/public'; -import { Schemas } from '../../vis_default_editor/public'; +import { Schemas } from '../../../../plugins/vis_default_editor/public'; import { Positions, ChartTypes, diff --git a/src/legacy/core_plugins/vis_type_vislib/public/pie.ts b/src/legacy/core_plugins/vis_type_vislib/public/pie.ts index 0f1bd93f5b5bd..2774836baa381 100644 --- a/src/legacy/core_plugins/vis_type_vislib/public/pie.ts +++ b/src/legacy/core_plugins/vis_type_vislib/public/pie.ts @@ -20,7 +20,7 @@ import { i18n } from '@kbn/i18n'; import { AggGroupNames } from '../../../../plugins/data/public'; -import { Schemas } from '../../vis_default_editor/public'; +import { Schemas } from '../../../../plugins/vis_default_editor/public'; import { PieOptions } from './components/options'; import { getPositions, Positions } from './utils/collections'; import { createVislibVisController } from './vis_controller'; diff --git a/src/legacy/core_plugins/vis_type_vislib/public/utils/common_config.tsx b/src/legacy/core_plugins/vis_type_vislib/public/utils/common_config.tsx index 6da40686a8b50..de867dc72bba7 100644 --- a/src/legacy/core_plugins/vis_type_vislib/public/utils/common_config.tsx +++ b/src/legacy/core_plugins/vis_type_vislib/public/utils/common_config.tsx @@ -20,7 +20,7 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; -import { VisOptionsProps } from '../../../vis_default_editor/public'; +import { VisOptionsProps } from 'src/plugins/vis_default_editor/public'; import { PointSeriesOptions, MetricsAxisOptions } from '../components/options'; import { ValidationWrapper } from '../components/common'; import { BasicVislibParams } from '../types'; diff --git a/src/plugins/vis_default_editor/README.md b/src/plugins/vis_default_editor/README.md new file mode 100644 index 0000000000000..8607dfe486ace --- /dev/null +++ b/src/plugins/vis_default_editor/README.md @@ -0,0 +1,16 @@ +# Visualization Deafult Editor plugin + +The default editor is used in most primary visualizations, e.x. `Area`, `Data table`, `Pie`, etc. +It acts as a container for a particular visualization and options tabs. Contains the default "Data" tab in `public/components/sidebar/data_tab.tsx`. +The plugin exposes the static `DefaultEditorController` class to consume. + +```ts +import { DefaultEditorController } from '../../vis_default_editor/public'; + +const editor = new DefaultEditorController( + element, + vis, + eventEmitter, + embeddableHandler +); +``` \ No newline at end of file diff --git a/src/legacy/core_plugins/vis_default_editor/public/_agg.scss b/src/plugins/vis_default_editor/public/_agg.scss similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/_agg.scss rename to src/plugins/vis_default_editor/public/_agg.scss diff --git a/src/legacy/core_plugins/vis_default_editor/public/_agg_params.scss b/src/plugins/vis_default_editor/public/_agg_params.scss similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/_agg_params.scss rename to src/plugins/vis_default_editor/public/_agg_params.scss diff --git a/src/legacy/core_plugins/vis_default_editor/public/_default.scss b/src/plugins/vis_default_editor/public/_default.scss similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/_default.scss rename to src/plugins/vis_default_editor/public/_default.scss diff --git a/src/legacy/core_plugins/vis_default_editor/public/_sidebar.scss b/src/plugins/vis_default_editor/public/_sidebar.scss similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/_sidebar.scss rename to src/plugins/vis_default_editor/public/_sidebar.scss diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/__snapshots__/agg.test.tsx.snap b/src/plugins/vis_default_editor/public/components/__snapshots__/agg.test.tsx.snap similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/__snapshots__/agg.test.tsx.snap rename to src/plugins/vis_default_editor/public/components/__snapshots__/agg.test.tsx.snap diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/__snapshots__/agg_group.test.tsx.snap b/src/plugins/vis_default_editor/public/components/__snapshots__/agg_group.test.tsx.snap similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/__snapshots__/agg_group.test.tsx.snap rename to src/plugins/vis_default_editor/public/components/__snapshots__/agg_group.test.tsx.snap diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg.test.tsx b/src/plugins/vis_default_editor/public/components/agg.test.tsx similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/agg.test.tsx rename to src/plugins/vis_default_editor/public/components/agg.test.tsx diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg.tsx b/src/plugins/vis_default_editor/public/components/agg.tsx similarity index 98% rename from src/legacy/core_plugins/vis_default_editor/public/components/agg.tsx rename to src/plugins/vis_default_editor/public/components/agg.tsx index 83fbf70c9099e..c7e3e609490f9 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/agg.tsx +++ b/src/plugins/vis_default_editor/public/components/agg.tsx @@ -28,14 +28,13 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { IAggConfig } from 'src/plugins/data/public'; +import { IAggConfig, TimeRange } from 'src/plugins/data/public'; import { DefaultEditorAggParams } from './agg_params'; import { DefaultEditorAggCommonProps } from './agg_common_props'; import { AGGS_ACTION_KEYS, AggsAction } from './agg_group_state'; import { RowsOrColumnsControl } from './controls/rows_or_columns'; import { RadiusRatioOptionControl } from './controls/radius_ratio_option'; import { getSchemaByName } from '../schemas'; -import { TimeRange } from '../../../../../plugins/data/public'; import { buildAggDescription } from './agg_params_helper'; export interface DefaultEditorAggProps extends DefaultEditorAggCommonProps { diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_add.tsx b/src/plugins/vis_default_editor/public/components/agg_add.tsx similarity index 98% rename from src/legacy/core_plugins/vis_default_editor/public/components/agg_add.tsx rename to src/plugins/vis_default_editor/public/components/agg_add.tsx index 9df4ea58e0f07..f2c2f8b4d0b94 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/agg_add.tsx +++ b/src/plugins/vis_default_editor/public/components/agg_add.tsx @@ -29,7 +29,7 @@ import { } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; -import { IAggConfig, AggGroupNames } from '../../../../../plugins/data/public'; +import { IAggConfig, AggGroupNames } from '../../../data/public'; import { Schema } from '../schemas'; interface DefaultEditorAggAddProps { diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_common_props.ts b/src/plugins/vis_default_editor/public/components/agg_common_props.ts similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/agg_common_props.ts rename to src/plugins/vis_default_editor/public/components/agg_common_props.ts diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_group.test.tsx b/src/plugins/vis_default_editor/public/components/agg_group.test.tsx similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/agg_group.test.tsx rename to src/plugins/vis_default_editor/public/components/agg_group.test.tsx diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_group.tsx b/src/plugins/vis_default_editor/public/components/agg_group.tsx similarity index 97% rename from src/legacy/core_plugins/vis_default_editor/public/components/agg_group.tsx rename to src/plugins/vis_default_editor/public/components/agg_group.tsx index 792595fd421f6..ecbc41f28003c 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/agg_group.tsx +++ b/src/plugins/vis_default_editor/public/components/agg_group.tsx @@ -30,7 +30,7 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { AggGroupNames, search, IAggConfig } from '../../../../../plugins/data/public'; +import { AggGroupNames, search, IAggConfig, TimeRange } from '../../../data/public'; import { DefaultEditorAgg } from './agg'; import { DefaultEditorAggAdd } from './agg_add'; import { AddSchema, ReorderAggs, DefaultEditorAggCommonProps } from './agg_common_props'; @@ -42,7 +42,6 @@ import { } from './agg_group_helper'; import { aggGroupReducer, initAggsState, AGGS_ACTION_KEYS } from './agg_group_state'; import { Schema } from '../schemas'; -import { TimeRange } from '../../../../../plugins/data/public'; export interface DefaultEditorAggGroupProps extends DefaultEditorAggCommonProps { schemas: Schema[]; diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_group_helper.test.ts b/src/plugins/vis_default_editor/public/components/agg_group_helper.test.ts similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/agg_group_helper.test.ts rename to src/plugins/vis_default_editor/public/components/agg_group_helper.test.ts diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_group_helper.tsx b/src/plugins/vis_default_editor/public/components/agg_group_helper.tsx similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/agg_group_helper.tsx rename to src/plugins/vis_default_editor/public/components/agg_group_helper.tsx diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_group_state.tsx b/src/plugins/vis_default_editor/public/components/agg_group_state.tsx similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/agg_group_state.tsx rename to src/plugins/vis_default_editor/public/components/agg_group_state.tsx diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_param.tsx b/src/plugins/vis_default_editor/public/components/agg_param.tsx similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/agg_param.tsx rename to src/plugins/vis_default_editor/public/components/agg_param.tsx diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_param_props.ts b/src/plugins/vis_default_editor/public/components/agg_param_props.ts similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/agg_param_props.ts rename to src/plugins/vis_default_editor/public/components/agg_param_props.ts diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_params.test.tsx b/src/plugins/vis_default_editor/public/components/agg_params.test.tsx similarity index 96% rename from src/legacy/core_plugins/vis_default_editor/public/components/agg_params.test.tsx rename to src/plugins/vis_default_editor/public/components/agg_params.test.tsx index 1c49ebf40640e..cac1b0851b92d 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/agg_params.test.tsx +++ b/src/plugins/vis_default_editor/public/components/agg_params.test.tsx @@ -25,8 +25,8 @@ import { DefaultEditorAggParams as PureDefaultEditorAggParams, DefaultEditorAggParamsProps, } from './agg_params'; -import { KibanaContextProvider } from '../../../../../plugins/kibana_react/public'; -import { dataPluginMock } from '../../../../../plugins/data/public/mocks'; +import { KibanaContextProvider } from '../../../kibana_react/public'; +import { dataPluginMock } from '../../../data/public/mocks'; import { EditorVisState } from './sidebar/state/reducers'; const mockEditorConfig = { diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_params.tsx b/src/plugins/vis_default_editor/public/components/agg_params.tsx similarity index 98% rename from src/legacy/core_plugins/vis_default_editor/public/components/agg_params.tsx rename to src/plugins/vis_default_editor/public/components/agg_params.tsx index b1555b76500d0..3674e39b558d2 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/agg_params.tsx +++ b/src/plugins/vis_default_editor/public/components/agg_params.tsx @@ -22,7 +22,7 @@ import { EuiForm, EuiAccordion, EuiSpacer } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import useUnmount from 'react-use/lib/useUnmount'; -import { IAggConfig, IndexPattern, AggGroupNames } from '../../../../../plugins/data/public'; +import { IAggConfig, IndexPattern, AggGroupNames } from '../../../data/public'; import { DefaultEditorAggSelect } from './agg_select'; import { DefaultEditorAggParam } from './agg_param'; @@ -40,7 +40,7 @@ import { import { DefaultEditorCommonProps } from './agg_common_props'; import { EditorParamConfig, TimeIntervalParam, FixedParam, getEditorConfig } from './utils'; import { Schema, getSchemaByName } from '../schemas'; -import { useKibana } from '../../../../../plugins/kibana_react/public'; +import { useKibana } from '../../../kibana_react/public'; import { VisDefaultEditorKibanaServices } from '../types'; const FIXED_VALUE_PROP = 'fixedValue'; diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_params_helper.test.ts b/src/plugins/vis_default_editor/public/components/agg_params_helper.test.ts similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/agg_params_helper.test.ts rename to src/plugins/vis_default_editor/public/components/agg_params_helper.test.ts diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_params_helper.ts b/src/plugins/vis_default_editor/public/components/agg_params_helper.ts similarity index 99% rename from src/legacy/core_plugins/vis_default_editor/public/components/agg_params_helper.ts rename to src/plugins/vis_default_editor/public/components/agg_params_helper.ts index 073cb7d5ac66c..a32bd76bafa5a 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/agg_params_helper.ts +++ b/src/plugins/vis_default_editor/public/components/agg_params_helper.ts @@ -34,7 +34,7 @@ import { AggParamEditorProps } from './agg_param_props'; import { aggParamsMap } from './agg_params_map'; import { EditorConfig } from './utils'; import { Schema, getSchemaByName } from '../schemas'; -import { search } from '../../../../../plugins/data/public'; +import { search } from '../../../data/public'; import { EditorVisState } from './sidebar/state/reducers'; interface ParamInstanceBase { diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_params_map.ts b/src/plugins/vis_default_editor/public/components/agg_params_map.ts similarity index 96% rename from src/legacy/core_plugins/vis_default_editor/public/components/agg_params_map.ts rename to src/plugins/vis_default_editor/public/components/agg_params_map.ts index 4517313b6fd6e..5af3cfc5b0928 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/agg_params_map.ts +++ b/src/plugins/vis_default_editor/public/components/agg_params_map.ts @@ -18,12 +18,7 @@ */ import * as controls from './controls'; -import { - AggGroupNames, - BUCKET_TYPES, - METRIC_TYPES, - search, -} from '../../../../../plugins/data/public'; +import { AggGroupNames, BUCKET_TYPES, METRIC_TYPES, search } from '../../../data/public'; import { wrapWithInlineComp } from './controls/utils'; const { siblingPipelineType, parentPipelineType } = search.aggs; diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_params_state.ts b/src/plugins/vis_default_editor/public/components/agg_params_state.ts similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/agg_params_state.ts rename to src/plugins/vis_default_editor/public/components/agg_params_state.ts diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_select.tsx b/src/plugins/vis_default_editor/public/components/agg_select.tsx similarity index 98% rename from src/legacy/core_plugins/vis_default_editor/public/components/agg_select.tsx rename to src/plugins/vis_default_editor/public/components/agg_select.tsx index 7ee432946f3c8..6cb76b18e24a6 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/agg_select.tsx +++ b/src/plugins/vis_default_editor/public/components/agg_select.tsx @@ -24,7 +24,7 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import { IAggType, IndexPattern } from 'src/plugins/data/public'; -import { useKibana } from '../../../../../plugins/kibana_react/public'; +import { useKibana } from '../../../kibana_react/public'; import { ComboBoxGroupedOptions } from '../utils'; import { AGG_TYPE_ACTION_KEYS, AggTypeAction } from './agg_params_state'; diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/__snapshots__/extended_bounds.test.tsx.snap b/src/plugins/vis_default_editor/public/components/controls/__snapshots__/extended_bounds.test.tsx.snap similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/__snapshots__/extended_bounds.test.tsx.snap rename to src/plugins/vis_default_editor/public/components/controls/__snapshots__/extended_bounds.test.tsx.snap diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/__snapshots__/metric_agg.test.tsx.snap b/src/plugins/vis_default_editor/public/components/controls/__snapshots__/metric_agg.test.tsx.snap similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/__snapshots__/metric_agg.test.tsx.snap rename to src/plugins/vis_default_editor/public/components/controls/__snapshots__/metric_agg.test.tsx.snap diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/__snapshots__/size.test.tsx.snap b/src/plugins/vis_default_editor/public/components/controls/__snapshots__/size.test.tsx.snap similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/__snapshots__/size.test.tsx.snap rename to src/plugins/vis_default_editor/public/components/controls/__snapshots__/size.test.tsx.snap diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/__snapshots__/top_aggregate.test.tsx.snap b/src/plugins/vis_default_editor/public/components/controls/__snapshots__/top_aggregate.test.tsx.snap similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/__snapshots__/top_aggregate.test.tsx.snap rename to src/plugins/vis_default_editor/public/components/controls/__snapshots__/top_aggregate.test.tsx.snap diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/agg_control_props.tsx b/src/plugins/vis_default_editor/public/components/controls/agg_control_props.tsx similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/agg_control_props.tsx rename to src/plugins/vis_default_editor/public/components/controls/agg_control_props.tsx diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/agg_utils.test.tsx b/src/plugins/vis_default_editor/public/components/controls/agg_utils.test.tsx similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/agg_utils.test.tsx rename to src/plugins/vis_default_editor/public/components/controls/agg_utils.test.tsx diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/auto_precision.tsx b/src/plugins/vis_default_editor/public/components/controls/auto_precision.tsx similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/auto_precision.tsx rename to src/plugins/vis_default_editor/public/components/controls/auto_precision.tsx diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/components/from_to_list.tsx b/src/plugins/vis_default_editor/public/components/controls/components/from_to_list.tsx similarity index 68% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/components/from_to_list.tsx rename to src/plugins/vis_default_editor/public/components/controls/components/from_to_list.tsx index e52b2c85b63fa..b874459a8e7d3 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/components/from_to_list.tsx +++ b/src/plugins/vis_default_editor/public/components/controls/components/from_to_list.tsx @@ -17,11 +17,11 @@ * under the License. */ -import React from 'react'; +import React, { useCallback } from 'react'; import { EuiFieldText, EuiFlexItem, EuiIcon } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { Ipv4Address } from '../../../../../../../plugins/kibana_utils/public'; +import { Ipv4Address } from '../../../../../kibana_utils/public'; import { InputList, InputListConfig, InputModel, InputObject, InputItem } from './input_list'; const EMPTY_STRING = ''; @@ -44,38 +44,42 @@ interface FromToListProps { setValidity(isValid: boolean): void; } -function FromToList({ showValidation, onBlur, ...rest }: FromToListProps) { - const fromToListConfig: InputListConfig = { - defaultValue: { - from: { value: '0.0.0.0', model: '0.0.0.0', isInvalid: false }, - to: { value: '255.255.255.255', model: '255.255.255.255', isInvalid: false }, +const defaultConfig = { + defaultValue: { + from: { value: '0.0.0.0', model: '0.0.0.0', isInvalid: false }, + to: { value: '255.255.255.255', model: '255.255.255.255', isInvalid: false }, + }, + validateClass: Ipv4Address, + getModelValue: (item: FromToObject = {}) => ({ + from: { + value: item.from || EMPTY_STRING, + model: item.from || EMPTY_STRING, + isInvalid: false, }, - validateClass: Ipv4Address, - getModelValue: (item: FromToObject = {}) => ({ - from: { - value: item.from || EMPTY_STRING, - model: item.from || EMPTY_STRING, - isInvalid: false, - }, - to: { value: item.to || EMPTY_STRING, model: item.to || EMPTY_STRING, isInvalid: false }, + to: { value: item.to || EMPTY_STRING, model: item.to || EMPTY_STRING, isInvalid: false }, + }), + getRemoveBtnAriaLabel: (item: FromToModel) => + i18n.translate('visDefaultEditor.controls.ipRanges.removeRangeAriaLabel', { + defaultMessage: 'Remove the range of {from} to {to}', + values: { from: item.from.value || '*', to: item.to.value || '*' }, }), - getRemoveBtnAriaLabel: (item: FromToModel) => - i18n.translate('visDefaultEditor.controls.ipRanges.removeRangeAriaLabel', { - defaultMessage: 'Remove the range of {from} to {to}', - values: { from: item.from.value || '*', to: item.to.value || '*' }, - }), - onChangeFn: ({ from, to }: FromToModel) => { - const result: FromToObject = {}; - if (from.model) { - result.from = from.model; - } - if (to.model) { - result.to = to.model; - } - return result; - }, - hasInvalidValuesFn: ({ from, to }: FromToModel) => from.isInvalid || to.isInvalid, - renderInputRow: (item: FromToModel, index, onChangeValue) => ( + onChangeFn: ({ from, to }: FromToModel) => { + const result: FromToObject = {}; + if (from.model) { + result.from = from.model; + } + if (to.model) { + result.to = to.model; + } + return result; + }, + hasInvalidValuesFn: ({ from, to }: FromToModel) => from.isInvalid || to.isInvalid, + modelNames: ['from', 'to'], +}; + +function FromToList({ showValidation, onBlur, ...rest }: FromToListProps) { + const renderInputRow = useCallback( + (item: FromToModel, index, onChangeValue) => ( <> ), - modelNames: ['from', 'to'], + [onBlur, showValidation] + ); + const fromToListConfig: InputListConfig = { + ...defaultConfig, + renderInputRow, }; return ; diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/components/input_list.tsx b/src/plugins/vis_default_editor/public/components/controls/components/input_list.tsx similarity index 75% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/components/input_list.tsx rename to src/plugins/vis_default_editor/public/components/controls/components/input_list.tsx index cc80d0073c904..639b69cd3d33c 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/components/input_list.tsx +++ b/src/plugins/vis_default_editor/public/components/controls/components/input_list.tsx @@ -17,7 +17,7 @@ * under the License. */ -import React, { useState, useEffect, Fragment } from 'react'; +import React, { useState, useEffect, Fragment, useCallback } from 'react'; import { isEmpty, isEqual, mapValues, omit, pick } from 'lodash'; import { EuiButtonIcon, @@ -70,7 +70,10 @@ interface InputListProps { } const generateId = htmlIdGenerator(); -const validateValue = (inputValue: string | undefined, config: InputListConfig) => { +const validateValue = ( + inputValue: string | undefined, + InputObject: InputListConfig['validateClass'] +) => { const result = { model: inputValue || '', isInvalid: false, @@ -80,7 +83,6 @@ const validateValue = (inputValue: string | undefined, config: InputListConfig) return result; } try { - const InputObject = config.validateClass; result.model = new InputObject(inputValue).toString(); result.isInvalid = false; return result; @@ -91,47 +93,60 @@ const validateValue = (inputValue: string | undefined, config: InputListConfig) }; function InputList({ config, list, onChange, setValidity }: InputListProps) { + const { defaultValue, getModelValue, modelNames, onChangeFn, validateClass } = config; const [models, setModels] = useState(() => list.map( item => ({ id: generateId(), - ...config.getModelValue(item), + ...getModelValue(item), } as InputModel) ) ); const hasInvalidValues = models.some(config.hasInvalidValuesFn); - const updateValues = (modelList: InputModel[]) => { - setModels(modelList); - onChange(modelList.map(config.onChangeFn)); - }; - const onChangeValue = (index: number, value: string, modelName: string) => { - const { model, isInvalid } = validateValue(value, config); - updateValues( - models.map((range, arrayIndex) => - arrayIndex === index - ? { - ...range, - [modelName]: { - value, - model, - isInvalid, - }, - } - : range - ) - ); - }; - const onDelete = (id: string) => updateValues(models.filter(model => model.id !== id)); - const onAdd = () => - updateValues([ - ...models, - { - id: generateId(), - ...config.getModelValue(), - } as InputModel, - ]); + const updateValues = useCallback( + (modelList: InputModel[]) => { + setModels(modelList); + onChange(modelList.map(onChangeFn)); + }, + [onChangeFn, onChange] + ); + const onChangeValue = useCallback( + (index: number, value: string, modelName: string) => { + const { model, isInvalid } = validateValue(value, validateClass); + updateValues( + models.map((range, arrayIndex) => + arrayIndex === index + ? { + ...range, + [modelName]: { + value, + model, + isInvalid, + }, + } + : range + ) + ); + }, + [models, updateValues, validateClass] + ); + const onDelete = useCallback( + (id: string) => updateValues(models.filter(model => model.id !== id)), + [models, updateValues] + ); + const onAdd = useCallback( + () => + updateValues([ + ...models, + { + id: generateId(), + ...getModelValue(), + } as InputModel, + ]), + [getModelValue, models, updateValues] + ); useEffect(() => { // resposible for setting up an initial value when there is no default value @@ -139,15 +154,15 @@ function InputList({ config, list, onChange, setValidity }: InputListProps) { updateValues([ { id: generateId(), - ...config.defaultValue, + ...defaultValue, } as InputModel, ]); } - }, []); + }, [defaultValue, list.length, updateValues]); useEffect(() => { setValidity(!hasInvalidValues); - }, [hasInvalidValues]); + }, [hasInvalidValues, setValidity]); useEffect(() => { // responsible for discarding changes @@ -155,7 +170,7 @@ function InputList({ config, list, onChange, setValidity }: InputListProps) { list.length !== models.length || list.some((item, index) => { // make model to be the same shape as stored value - const model: InputObject = mapValues(pick(models[index], config.modelNames), 'model'); + const model: InputObject = mapValues(pick(models[index], modelNames), 'model'); // we need to skip empty values since they are not stored in saved object return !isEqual(item, omit(model, isEmpty)); @@ -166,12 +181,12 @@ function InputList({ config, list, onChange, setValidity }: InputListProps) { item => ({ id: generateId(), - ...config.getModelValue(item), + ...getModelValue(item), } as InputModel) ) ); } - }, [list]); + }, [getModelValue, list, modelNames, models]); return ( <> diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/components/mask_list.tsx b/src/plugins/vis_default_editor/public/components/controls/components/mask_list.tsx similarity index 62% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/components/mask_list.tsx rename to src/plugins/vis_default_editor/public/components/controls/components/mask_list.tsx index f6edecbbcbd70..560213fc08ff0 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/components/mask_list.tsx +++ b/src/plugins/vis_default_editor/public/components/controls/components/mask_list.tsx @@ -17,12 +17,12 @@ * under the License. */ -import React from 'react'; +import React, { useCallback } from 'react'; import { EuiFieldText, EuiFlexItem } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { InputList, InputListConfig, InputObject, InputModel, InputItem } from './input_list'; -import { search } from '../../../../../../../plugins/data/public'; +import { search } from '../../../../../data/public'; const EMPTY_STRING = ''; @@ -42,36 +42,40 @@ interface MaskListProps { setValidity(isValid: boolean): void; } -function MaskList({ showValidation, onBlur, ...rest }: MaskListProps) { - const maskListConfig: InputListConfig = { - defaultValue: { - mask: { model: '0.0.0.0/1', value: '0.0.0.0/1', isInvalid: false }, +const defaultConfig = { + defaultValue: { + mask: { model: '0.0.0.0/1', value: '0.0.0.0/1', isInvalid: false }, + }, + validateClass: search.aggs.CidrMask, + getModelValue: (item: MaskObject = {}) => ({ + mask: { + model: item.mask || EMPTY_STRING, + value: item.mask || EMPTY_STRING, + isInvalid: false, }, - validateClass: search.aggs.CidrMask, - getModelValue: (item: MaskObject = {}) => ({ - mask: { - model: item.mask || EMPTY_STRING, - value: item.mask || EMPTY_STRING, - isInvalid: false, - }, - }), - getRemoveBtnAriaLabel: (item: MaskModel) => - item.mask.value - ? i18n.translate('visDefaultEditor.controls.ipRanges.removeCidrMaskButtonAriaLabel', { - defaultMessage: 'Remove the CIDR mask value of {mask}', - values: { mask: item.mask.value }, - }) - : i18n.translate('visDefaultEditor.controls.ipRanges.removeEmptyCidrMaskButtonAriaLabel', { - defaultMessage: 'Remove the CIDR mask default value', - }), - onChangeFn: ({ mask }: MaskModel) => { - if (mask.model) { - return { mask: mask.model }; - } - return {}; - }, - hasInvalidValuesFn: ({ mask }) => mask.isInvalid, - renderInputRow: ({ mask }: MaskModel, index, onChangeValue) => ( + }), + getRemoveBtnAriaLabel: (item: MaskModel) => + item.mask.value + ? i18n.translate('visDefaultEditor.controls.ipRanges.removeCidrMaskButtonAriaLabel', { + defaultMessage: 'Remove the CIDR mask value of {mask}', + values: { mask: item.mask.value }, + }) + : i18n.translate('visDefaultEditor.controls.ipRanges.removeEmptyCidrMaskButtonAriaLabel', { + defaultMessage: 'Remove the CIDR mask default value', + }), + onChangeFn: ({ mask }: MaskModel) => { + if (mask.model) { + return { mask: mask.model }; + } + return {}; + }, + hasInvalidValuesFn: ({ mask }: MaskModel) => mask.isInvalid, + modelNames: 'mask', +}; + +function MaskList({ showValidation, onBlur, ...rest }: MaskListProps) { + const renderInputRow = useCallback( + ({ mask }: MaskModel, index, onChangeValue) => ( ), - modelNames: 'mask', + [onBlur, showValidation] + ); + const maskListConfig: InputListConfig = { + ...defaultConfig, + renderInputRow, }; return ; diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/components/number_list/__snapshots__/number_list.test.tsx.snap b/src/plugins/vis_default_editor/public/components/controls/components/number_list/__snapshots__/number_list.test.tsx.snap similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/components/number_list/__snapshots__/number_list.test.tsx.snap rename to src/plugins/vis_default_editor/public/components/controls/components/number_list/__snapshots__/number_list.test.tsx.snap diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/components/number_list/__snapshots__/number_row.test.tsx.snap b/src/plugins/vis_default_editor/public/components/controls/components/number_list/__snapshots__/number_row.test.tsx.snap similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/components/number_list/__snapshots__/number_row.test.tsx.snap rename to src/plugins/vis_default_editor/public/components/controls/components/number_list/__snapshots__/number_row.test.tsx.snap diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/components/number_list/index.ts b/src/plugins/vis_default_editor/public/components/controls/components/number_list/index.ts similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/components/number_list/index.ts rename to src/plugins/vis_default_editor/public/components/controls/components/number_list/index.ts diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/components/number_list/number_list.test.tsx b/src/plugins/vis_default_editor/public/components/controls/components/number_list/number_list.test.tsx similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/components/number_list/number_list.test.tsx rename to src/plugins/vis_default_editor/public/components/controls/components/number_list/number_list.test.tsx diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/components/number_list/number_list.tsx b/src/plugins/vis_default_editor/public/components/controls/components/number_list/number_list.tsx similarity index 98% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/components/number_list/number_list.tsx rename to src/plugins/vis_default_editor/public/components/controls/components/number_list/number_list.tsx index a43c66c2e08cc..b4683e47979ce 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/components/number_list/number_list.tsx +++ b/src/plugins/vis_default_editor/public/components/controls/components/number_list/number_list.tsx @@ -79,7 +79,7 @@ function NumberList({ if (!numberArray.length) { onChange([models[0].value as number]); } - }, []); + }, [models, numberArray.length, onChange]); const isValid = !hasInvalidValues(models); useValidation(setValidity, isValid); @@ -109,7 +109,7 @@ function NumberList({ }) ); }, - [numberRange, models, onUpdate] + [models, onUpdate] ); // Add an item to the end of the list diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/components/number_list/number_row.test.tsx b/src/plugins/vis_default_editor/public/components/controls/components/number_list/number_row.test.tsx similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/components/number_list/number_row.test.tsx rename to src/plugins/vis_default_editor/public/components/controls/components/number_list/number_row.test.tsx diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/components/number_list/number_row.tsx b/src/plugins/vis_default_editor/public/components/controls/components/number_list/number_row.tsx similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/components/number_list/number_row.tsx rename to src/plugins/vis_default_editor/public/components/controls/components/number_list/number_row.tsx diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/components/number_list/range.test.ts b/src/plugins/vis_default_editor/public/components/controls/components/number_list/range.test.ts similarity index 98% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/components/number_list/range.test.ts rename to src/plugins/vis_default_editor/public/components/controls/components/number_list/range.test.ts index e9090e5b38ef7..a19034d3c8e92 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/components/number_list/range.test.ts +++ b/src/plugins/vis_default_editor/public/components/controls/components/number_list/range.test.ts @@ -108,7 +108,6 @@ describe('Range parsing utility', () => { }; forOwn(tests, (spec, str: any) => { - // eslint-disable-next-line jest/valid-describe describe(str, () => { const range = parseRange(str); diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/components/number_list/range.ts b/src/plugins/vis_default_editor/public/components/controls/components/number_list/range.ts similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/components/number_list/range.ts rename to src/plugins/vis_default_editor/public/components/controls/components/number_list/range.ts diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/components/number_list/utils.test.ts b/src/plugins/vis_default_editor/public/components/controls/components/number_list/utils.test.ts similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/components/number_list/utils.test.ts rename to src/plugins/vis_default_editor/public/components/controls/components/number_list/utils.test.ts diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/components/number_list/utils.ts b/src/plugins/vis_default_editor/public/components/controls/components/number_list/utils.ts similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/components/number_list/utils.ts rename to src/plugins/vis_default_editor/public/components/controls/components/number_list/utils.ts diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/date_ranges.test.tsx b/src/plugins/vis_default_editor/public/components/controls/date_ranges.test.tsx similarity index 95% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/date_ranges.test.tsx rename to src/plugins/vis_default_editor/public/components/controls/date_ranges.test.tsx index 6b1a4dca7b84f..b844fdfb82256 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/date_ranges.test.tsx +++ b/src/plugins/vis_default_editor/public/components/controls/date_ranges.test.tsx @@ -20,8 +20,8 @@ import React from 'react'; import { mountWithIntl } from 'test_utils/enzyme_helpers'; import { DateRangesParamEditor } from './date_ranges'; -import { KibanaContextProvider } from '../../../../../../plugins/kibana_react/public'; -import { docLinksServiceMock } from '../../../../../../core/public/mocks'; +import { KibanaContextProvider } from '../../../../kibana_react/public'; +import { docLinksServiceMock } from '../../../../../core/public/mocks'; describe('DateRangesParamEditor component', () => { let setValue: jest.Mock; diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/date_ranges.tsx b/src/plugins/vis_default_editor/public/components/controls/date_ranges.tsx similarity index 90% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/date_ranges.tsx rename to src/plugins/vis_default_editor/public/components/controls/date_ranges.tsx index 15e864bfd026d..57f4c7d04019b 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/date_ranges.tsx +++ b/src/plugins/vis_default_editor/public/components/controls/date_ranges.tsx @@ -17,7 +17,7 @@ * under the License. */ -import React, { Fragment, useState, useEffect } from 'react'; +import React, { Fragment, useState, useEffect, useCallback } from 'react'; import { htmlIdGenerator, EuiButtonIcon, @@ -36,8 +36,9 @@ import dateMath from '@elastic/datemath'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; import { isEqual, omit } from 'lodash'; +import { useMount } from 'react-use'; -import { useKibana } from '../../../../../../plugins/kibana_react/public'; +import { useKibana } from '../../../../kibana_react/public'; import { AggParamEditorProps } from '../agg_param_props'; const FROM_PLACEHOLDER = '\u2212\u221E'; @@ -72,12 +73,26 @@ function DateRangesParamEditor({ ({ from, to }) => (!from && !to) || !validateDateMath(from) || !validateDateMath(to) ); - // set up an initial range when there is no default range - useEffect(() => { + const updateRanges = useCallback( + (rangeValues: DateRangeValuesModel[]) => { + // do not set internal id parameter into saved object + setValue(rangeValues.map(range => omit(range, 'id'))); + setRanges(rangeValues); + }, + [setValue] + ); + + const onAddRange = useCallback(() => updateRanges([...ranges, { id: generateId() }]), [ + ranges, + updateRanges, + ]); + + useMount(() => { + // set up an initial range when there is no default range if (!value.length) { onAddRange(); } - }, []); + }); useEffect(() => { // responsible for discarding changes @@ -87,18 +102,12 @@ function DateRangesParamEditor({ ) { setRanges(value.map(range => ({ ...range, id: generateId() }))); } - }, [value]); + }, [ranges, value]); useEffect(() => { setValidity(!hasInvalidRange); - }, [hasInvalidRange]); - - const updateRanges = (rangeValues: DateRangeValuesModel[]) => { - // do not set internal id parameter into saved object - setValue(rangeValues.map(range => omit(range, 'id'))); - setRanges(rangeValues); - }; - const onAddRange = () => updateRanges([...ranges, { id: generateId() }]); + }, [hasInvalidRange, setValidity]); + const onRemoveRange = (id: string) => updateRanges(ranges.filter(range => range.id !== id)); const onChangeRange = (id: string, key: string, newValue: string) => updateRanges( diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/drop_partials.tsx b/src/plugins/vis_default_editor/public/components/controls/drop_partials.tsx similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/drop_partials.tsx rename to src/plugins/vis_default_editor/public/components/controls/drop_partials.tsx diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/extended_bounds.test.tsx b/src/plugins/vis_default_editor/public/components/controls/extended_bounds.test.tsx similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/extended_bounds.test.tsx rename to src/plugins/vis_default_editor/public/components/controls/extended_bounds.test.tsx diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/extended_bounds.tsx b/src/plugins/vis_default_editor/public/components/controls/extended_bounds.tsx similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/extended_bounds.tsx rename to src/plugins/vis_default_editor/public/components/controls/extended_bounds.tsx diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/field.test.tsx b/src/plugins/vis_default_editor/public/components/controls/field.test.tsx similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/field.test.tsx rename to src/plugins/vis_default_editor/public/components/controls/field.test.tsx diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/field.tsx b/src/plugins/vis_default_editor/public/components/controls/field.tsx similarity index 97% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/field.tsx rename to src/plugins/vis_default_editor/public/components/controls/field.tsx index fc1cbb51b70a7..42086004a12dc 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/field.tsx +++ b/src/plugins/vis_default_editor/public/components/controls/field.tsx @@ -18,7 +18,8 @@ */ import { get } from 'lodash'; -import React, { useEffect, useState, useCallback } from 'react'; +import React, { useState, useCallback } from 'react'; +import { useMount } from 'react-use'; import { EuiComboBox, EuiComboBoxOptionOption, EuiFormRow } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; @@ -84,8 +85,7 @@ function FieldParamEditor({ const showErrorMessage = (showValidation || !indexedFields.length) && !isValid; useValidation(setValidity, isValid); - - useEffect(() => { + useMount(() => { // set field if only one available if (indexedFields.length !== 1) { return; @@ -98,7 +98,7 @@ function FieldParamEditor({ } else if (indexedField.options.length === 1) { setValue(indexedField.options[0].target); } - }, []); + }); const onSearchChange = useCallback(searchValue => setIsDirty(Boolean(searchValue)), []); diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/filter.tsx b/src/plugins/vis_default_editor/public/components/controls/filter.tsx similarity index 99% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/filter.tsx rename to src/plugins/vis_default_editor/public/components/controls/filter.tsx index e2e7c2895093e..16aaff47f49c3 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/filter.tsx +++ b/src/plugins/vis_default_editor/public/components/controls/filter.tsx @@ -21,7 +21,7 @@ import React, { useState } from 'react'; import { EuiForm, EuiButtonIcon, EuiFieldText, EuiFormRow, EuiSpacer } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { IAggConfig, Query, QueryStringInput } from '../../../../../../plugins/data/public'; +import { IAggConfig, Query, QueryStringInput } from '../../../../data/public'; interface FilterRowProps { id: string; diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/filters.tsx b/src/plugins/vis_default_editor/public/components/controls/filters.tsx similarity index 96% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/filters.tsx rename to src/plugins/vis_default_editor/public/components/controls/filters.tsx index be4c62ab08aa2..d4e698f655c5e 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/filters.tsx +++ b/src/plugins/vis_default_editor/public/components/controls/filters.tsx @@ -21,9 +21,10 @@ import React, { useState, useEffect } from 'react'; import { omit, isEqual } from 'lodash'; import { htmlIdGenerator, EuiButton, EuiSpacer } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; +import { useMount } from 'react-use'; import { Query } from 'src/plugins/data/public'; -import { useKibana } from '../../../../../../plugins/kibana_react/public'; +import { useKibana } from '../../../../kibana_react/public'; import { FilterRow } from './filter'; import { AggParamEditorProps } from '../agg_param_props'; @@ -40,10 +41,10 @@ function FiltersParamEditor({ agg, value = [], setValue }: AggParamEditorProps ({ ...filter, id: generateId() })) ); - useEffect(() => { + useMount(() => { // set parsed values into model after initialization setValue(filters.map(filter => omit({ ...filter, input: filter.input }, 'id'))); - }, []); + }); useEffect(() => { // responsible for discarding changes @@ -53,7 +54,7 @@ function FiltersParamEditor({ agg, value = [], setValue }: AggParamEditorProps ({ ...filter, id: generateId() }))); } - }, [value]); + }, [filters, value]); const updateFilters = (updatedFilters: FilterValue[]) => { // do not set internal id parameter into saved object diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/has_extended_bounds.tsx b/src/plugins/vis_default_editor/public/components/controls/has_extended_bounds.tsx similarity index 73% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/has_extended_bounds.tsx rename to src/plugins/vis_default_editor/public/components/controls/has_extended_bounds.tsx index 90b7cb03b7a5b..a316a087c8bcb 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/has_extended_bounds.tsx +++ b/src/plugins/vis_default_editor/public/components/controls/has_extended_bounds.tsx @@ -17,22 +17,32 @@ * under the License. */ -import React, { useEffect } from 'react'; +import React, { useEffect, useRef } from 'react'; import { i18n } from '@kbn/i18n'; -import { search } from '../../../../../../plugins/data/public'; +import { search } from '../../../../data/public'; import { SwitchParamEditor } from './switch'; import { AggParamEditorProps } from '../agg_param_props'; const { isType } = search.aggs; function HasExtendedBoundsParamEditor(props: AggParamEditorProps) { + const { agg, setValue, value } = props; + const minDocCount = useRef(agg.params.min_doc_count); + useEffect(() => { - props.setValue(props.value && props.agg.params.min_doc_count); - }, [props.agg.params.min_doc_count]); + if (minDocCount.current !== agg.params.min_doc_count) { + // The "Extend bounds" param is only enabled when "Show empty buckets" is turned on. + // So if "Show empty buckets" is changed, "Extend bounds" should reflect changes + minDocCount.current = agg.params.min_doc_count; + + setValue(value && agg.params.min_doc_count); + } + }, [agg.params.min_doc_count, setValue, value]); return ( ) { !props.agg.params.min_doc_count || !(isType('number')(props.agg) || isType('date')(props.agg)) } - {...props} /> ); } diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/index.ts b/src/plugins/vis_default_editor/public/components/controls/index.ts similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/index.ts rename to src/plugins/vis_default_editor/public/components/controls/index.ts diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/ip_range_type.tsx b/src/plugins/vis_default_editor/public/components/controls/ip_range_type.tsx similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/ip_range_type.tsx rename to src/plugins/vis_default_editor/public/components/controls/ip_range_type.tsx diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/ip_ranges.tsx b/src/plugins/vis_default_editor/public/components/controls/ip_ranges.tsx similarity index 79% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/ip_ranges.tsx rename to src/plugins/vis_default_editor/public/components/controls/ip_ranges.tsx index c4b90649aaaae..5ffa8088a9546 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/ip_ranges.tsx +++ b/src/plugins/vis_default_editor/public/components/controls/ip_ranges.tsx @@ -17,7 +17,7 @@ * under the License. */ -import React from 'react'; +import React, { useCallback } from 'react'; import { EuiFormRow } from '@elastic/eui'; import { FromToList, FromToObject } from './components/from_to_list'; @@ -38,12 +38,22 @@ function IpRangesParamEditor({ setValidity, showValidation, }: AggParamEditorProps) { - const handleChange = (modelName: IpRangeTypes, items: Array) => { - setValue({ - ...value, - [modelName]: items, - }); - }; + const handleMaskListChange = useCallback( + (items: MaskObject[]) => + setValue({ + ...value, + [IpRangeTypes.MASK]: items, + }), + [setValue, value] + ); + const handleFromToListChange = useCallback( + (items: FromToObject[]) => + setValue({ + ...value, + [IpRangeTypes.FROM_TO]: items, + }), + [setValue, value] + ); return ( @@ -52,7 +62,7 @@ function IpRangesParamEditor({ list={value.mask} showValidation={showValidation} onBlur={setTouched} - onChange={items => handleChange(IpRangeTypes.MASK, items)} + onChange={handleMaskListChange} setValidity={setValidity} /> ) : ( @@ -60,7 +70,7 @@ function IpRangesParamEditor({ list={value.fromTo} showValidation={showValidation} onBlur={setTouched} - onChange={items => handleChange(IpRangeTypes.FROM_TO, items)} + onChange={handleFromToListChange} setValidity={setValidity} /> )} diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/is_filtered_by_collar.tsx b/src/plugins/vis_default_editor/public/components/controls/is_filtered_by_collar.tsx similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/is_filtered_by_collar.tsx rename to src/plugins/vis_default_editor/public/components/controls/is_filtered_by_collar.tsx diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/metric_agg.test.tsx b/src/plugins/vis_default_editor/public/components/controls/metric_agg.test.tsx similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/metric_agg.test.tsx rename to src/plugins/vis_default_editor/public/components/controls/metric_agg.test.tsx diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/metric_agg.tsx b/src/plugins/vis_default_editor/public/components/controls/metric_agg.tsx similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/metric_agg.tsx rename to src/plugins/vis_default_editor/public/components/controls/metric_agg.tsx diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/min_doc_count.tsx b/src/plugins/vis_default_editor/public/components/controls/min_doc_count.tsx similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/min_doc_count.tsx rename to src/plugins/vis_default_editor/public/components/controls/min_doc_count.tsx diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/missing_bucket.tsx b/src/plugins/vis_default_editor/public/components/controls/missing_bucket.tsx similarity index 93% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/missing_bucket.tsx rename to src/plugins/vis_default_editor/public/components/controls/missing_bucket.tsx index 7010f0d53e569..7d4d2230bd766 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/missing_bucket.tsx +++ b/src/plugins/vis_default_editor/public/components/controls/missing_bucket.tsx @@ -21,20 +21,22 @@ import React, { useEffect } from 'react'; import { i18n } from '@kbn/i18n'; import { SwitchParamEditor } from './switch'; -import { search } from '../../../../../../plugins/data/public'; +import { search } from '../../../../data/public'; import { AggParamEditorProps } from '../agg_param_props'; function MissingBucketParamEditor(props: AggParamEditorProps) { const fieldTypeIsNotString = !search.aggs.isStringType(props.agg); + const { setValue } = props; useEffect(() => { if (fieldTypeIsNotString) { - props.setValue(false); + setValue(false); } - }, [fieldTypeIsNotString]); + }, [fieldTypeIsNotString, setValue]); return ( ) { } )} disabled={fieldTypeIsNotString} - {...props} /> ); } diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/number_interval.tsx b/src/plugins/vis_default_editor/public/components/controls/number_interval.tsx similarity index 99% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/number_interval.tsx rename to src/plugins/vis_default_editor/public/components/controls/number_interval.tsx index 6ab5ee2d260a1..02bf680734526 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/number_interval.tsx +++ b/src/plugins/vis_default_editor/public/components/controls/number_interval.tsx @@ -61,7 +61,7 @@ function NumberIntervalParamEditor({ useEffect(() => { setValidity(isValid); - }, [isValid]); + }, [isValid, setValidity]); const onChange = useCallback( ({ target }: React.ChangeEvent) => diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/order.tsx b/src/plugins/vis_default_editor/public/components/controls/order.tsx similarity index 98% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/order.tsx rename to src/plugins/vis_default_editor/public/components/controls/order.tsx index 8f63662d928c1..e609bf9adf790 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/order.tsx +++ b/src/plugins/vis_default_editor/public/components/controls/order.tsx @@ -39,7 +39,7 @@ function OrderParamEditor({ useEffect(() => { setValidity(isValid); - }, [isValid]); + }, [isValid, setValidity]); // @ts-ignore return ( diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/order_agg.test.tsx b/src/plugins/vis_default_editor/public/components/controls/order_agg.test.tsx similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/order_agg.test.tsx rename to src/plugins/vis_default_editor/public/components/controls/order_agg.test.tsx diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/order_agg.tsx b/src/plugins/vis_default_editor/public/components/controls/order_agg.tsx similarity index 97% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/order_agg.tsx rename to src/plugins/vis_default_editor/public/components/controls/order_agg.tsx index 41672bc192fab..c5a35cbbd7ab1 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/order_agg.tsx +++ b/src/plugins/vis_default_editor/public/components/controls/order_agg.tsx @@ -20,7 +20,7 @@ import React, { useEffect } from 'react'; import { EuiSpacer } from '@elastic/eui'; -import { AggParamType, IAggConfig, AggGroupNames } from '../../../../../../plugins/data/public'; +import { AggParamType, IAggConfig, AggGroupNames } from '../../../../data/public'; import { useSubAggParamsHandlers } from './utils'; import { AggParamEditorProps } from '../agg_param_props'; import { DefaultEditorAggParams } from '../agg_params'; @@ -47,7 +47,7 @@ function OrderAggParamEditor({ if (orderBy !== 'custom' && value) { setValue(undefined); } - }, [orderBy]); + }, [agg, aggParam, orderBy, setValue, value]); const { onAggTypeChange, setAggParamValue } = useSubAggParamsHandlers( agg, diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/order_by.tsx b/src/plugins/vis_default_editor/public/components/controls/order_by.tsx similarity index 94% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/order_by.tsx rename to src/plugins/vis_default_editor/public/components/controls/order_by.tsx index 9f1aaa54a8ca3..47b12f4340d42 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/order_by.tsx +++ b/src/plugins/vis_default_editor/public/components/controls/order_by.tsx @@ -17,9 +17,10 @@ * under the License. */ -import React, { useEffect } from 'react'; +import React from 'react'; import { EuiFormRow, EuiSelect } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import { useMount } from 'react-use'; import { isCompatibleAggregation, @@ -28,7 +29,7 @@ import { useValidation, } from './utils'; import { AggParamEditorProps } from '../agg_param_props'; -import { search } from '../../../../../../plugins/data/public'; +import { search } from '../../../../data/public'; const { termsAggFilter } = search.aggs; const DEFAULT_VALUE = '_key'; @@ -58,8 +59,7 @@ function OrderByParamEditor({ const isValid = !!value; useValidation(setValidity, isValid); - - useEffect(() => { + useMount(() => { // setup the initial value of orderBy if (!value) { let respAgg = { id: DEFAULT_VALUE }; @@ -70,7 +70,7 @@ function OrderByParamEditor({ setValue(respAgg.id); } - }, []); + }); useFallbackMetric(setValue, termsAggFilter, metricAggs, value, DEFAULT_VALUE); diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/other_bucket.tsx b/src/plugins/vis_default_editor/public/components/controls/other_bucket.tsx similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/other_bucket.tsx rename to src/plugins/vis_default_editor/public/components/controls/other_bucket.tsx diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/percentile_ranks.tsx b/src/plugins/vis_default_editor/public/components/controls/percentile_ranks.tsx similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/percentile_ranks.tsx rename to src/plugins/vis_default_editor/public/components/controls/percentile_ranks.tsx diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/percentiles.test.tsx b/src/plugins/vis_default_editor/public/components/controls/percentiles.test.tsx similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/percentiles.test.tsx rename to src/plugins/vis_default_editor/public/components/controls/percentiles.test.tsx diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/percentiles.tsx b/src/plugins/vis_default_editor/public/components/controls/percentiles.tsx similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/percentiles.tsx rename to src/plugins/vis_default_editor/public/components/controls/percentiles.tsx diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/precision.tsx b/src/plugins/vis_default_editor/public/components/controls/precision.tsx similarity index 95% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/precision.tsx rename to src/plugins/vis_default_editor/public/components/controls/precision.tsx index df71e72ee6c61..ad2011513b171 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/precision.tsx +++ b/src/plugins/vis_default_editor/public/components/controls/precision.tsx @@ -22,7 +22,7 @@ import React from 'react'; import { EuiRange, EuiFormRow } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { useKibana } from '../../../../../../plugins/kibana_react/public'; +import { useKibana } from '../../../../kibana_react/public'; import { AggParamEditorProps } from '../agg_param_props'; function PrecisionParamEditor({ agg, value, setValue }: AggParamEditorProps) { diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/radius_ratio_option.tsx b/src/plugins/vis_default_editor/public/components/controls/radius_ratio_option.tsx similarity index 95% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/radius_ratio_option.tsx rename to src/plugins/vis_default_editor/public/components/controls/radius_ratio_option.tsx index c64b079e4f802..86c4431b6d5ed 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/radius_ratio_option.tsx +++ b/src/plugins/vis_default_editor/public/components/controls/radius_ratio_option.tsx @@ -17,10 +17,11 @@ * under the License. */ -import React, { useEffect, useCallback } from 'react'; +import React, { useCallback } from 'react'; import { EuiFormRow, EuiIconTip, EuiRange, EuiSpacer } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; +import { useMount } from 'react-use'; import { AggControlProps } from './agg_control_props'; @@ -44,11 +45,11 @@ function RadiusRatioOptionControl({ editorStateParams, setStateParamValue }: Agg ); - useEffect(() => { + useMount(() => { if (!editorStateParams.radiusRatio) { setStateParamValue(PARAM_NAME, DEFAULT_VALUE); } - }, []); + }); const onChange = useCallback( (e: React.ChangeEvent | React.MouseEvent) => diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/range_control.tsx b/src/plugins/vis_default_editor/public/components/controls/range_control.tsx similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/range_control.tsx rename to src/plugins/vis_default_editor/public/components/controls/range_control.tsx diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/ranges.tsx b/src/plugins/vis_default_editor/public/components/controls/ranges.tsx similarity index 91% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/ranges.tsx rename to src/plugins/vis_default_editor/public/components/controls/ranges.tsx index 27de9dfe68ee0..5c6438b400408 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/ranges.tsx +++ b/src/plugins/vis_default_editor/public/components/controls/ranges.tsx @@ -17,7 +17,7 @@ * under the License. */ -import React, { Fragment, useState, useEffect } from 'react'; +import React, { Fragment, useCallback, useState, useEffect } from 'react'; import { htmlIdGenerator, EuiButtonIcon, @@ -76,13 +76,44 @@ function RangesParamEditor({ validateRange, }: RangesParamEditorProps) { const [ranges, setRanges] = useState(() => value.map(range => ({ ...range, id: generateId() }))); + const updateRanges = useCallback( + (rangeValues: RangeValuesModel[]) => { + // do not set internal id parameter into saved object + setValue(rangeValues.map(range => omit(range, 'id'))); + setRanges(rangeValues); + + if (setTouched) { + setTouched(true); + } + }, + [setTouched, setValue] + ); + const onAddRange = useCallback( + () => + addRangeValues + ? updateRanges([...ranges, { ...addRangeValues(), id: generateId() }]) + : updateRanges([...ranges, { id: generateId() }]), + [addRangeValues, ranges, updateRanges] + ); + const onRemoveRange = (id: string) => updateRanges(ranges.filter(range => range.id !== id)); + const onChangeRange = (id: string, key: string, newValue: string) => + updateRanges( + ranges.map(range => + range.id === id + ? { + ...range, + [key]: newValue === '' ? undefined : parseFloat(newValue), + } + : range + ) + ); // set up an initial range when there is no default range useEffect(() => { if (!value.length) { onAddRange(); } - }, []); + }, [onAddRange, value.length]); useEffect(() => { // responsible for discarding changes @@ -92,33 +123,7 @@ function RangesParamEditor({ ) { setRanges(value.map(range => ({ ...range, id: generateId() }))); } - }, [value]); - - const updateRanges = (rangeValues: RangeValuesModel[]) => { - // do not set internal id parameter into saved object - setValue(rangeValues.map(range => omit(range, 'id'))); - setRanges(rangeValues); - - if (setTouched) { - setTouched(true); - } - }; - const onAddRange = () => - addRangeValues - ? updateRanges([...ranges, { ...addRangeValues(), id: generateId() }]) - : updateRanges([...ranges, { id: generateId() }]); - const onRemoveRange = (id: string) => updateRanges(ranges.filter(range => range.id !== id)); - const onChangeRange = (id: string, key: string, newValue: string) => - updateRanges( - ranges.map(range => - range.id === id - ? { - ...range, - [key]: newValue === '' ? undefined : parseFloat(newValue), - } - : range - ) - ); + }, [ranges, value]); const hasInvalidRange = validateRange && diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/raw_json.tsx b/src/plugins/vis_default_editor/public/components/controls/raw_json.tsx similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/raw_json.tsx rename to src/plugins/vis_default_editor/public/components/controls/raw_json.tsx diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/rows_or_columns.tsx b/src/plugins/vis_default_editor/public/components/controls/rows_or_columns.tsx similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/rows_or_columns.tsx rename to src/plugins/vis_default_editor/public/components/controls/rows_or_columns.tsx diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/scale_metrics.tsx b/src/plugins/vis_default_editor/public/components/controls/scale_metrics.tsx similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/scale_metrics.tsx rename to src/plugins/vis_default_editor/public/components/controls/scale_metrics.tsx diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/size.test.tsx b/src/plugins/vis_default_editor/public/components/controls/size.test.tsx similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/size.test.tsx rename to src/plugins/vis_default_editor/public/components/controls/size.test.tsx diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/size.tsx b/src/plugins/vis_default_editor/public/components/controls/size.tsx similarity index 98% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/size.tsx rename to src/plugins/vis_default_editor/public/components/controls/size.tsx index 824ec4aeb253c..9f55eb9212dee 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/size.tsx +++ b/src/plugins/vis_default_editor/public/components/controls/size.tsx @@ -48,7 +48,7 @@ function SizeParamEditor({ useEffect(() => { setValidity(isValid); - }, [isValid]); + }, [isValid, setValidity]); return ( { setValidity(isValid); - }, [isValid]); + }, [isValid, setValidity]); const onChange = useCallback(ev => setValue(ev.target.value), [setValue]); diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/sub_agg.tsx b/src/plugins/vis_default_editor/public/components/controls/sub_agg.tsx similarity index 97% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/sub_agg.tsx rename to src/plugins/vis_default_editor/public/components/controls/sub_agg.tsx index c9f53a68b3e83..ee0fbd8532ce9 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/sub_agg.tsx +++ b/src/plugins/vis_default_editor/public/components/controls/sub_agg.tsx @@ -20,7 +20,7 @@ import React, { useEffect } from 'react'; import { EuiSpacer } from '@elastic/eui'; -import { AggParamType, IAggConfig, AggGroupNames } from '../../../../../../plugins/data/public'; +import { AggParamType, IAggConfig, AggGroupNames } from '../../../../data/public'; import { useSubAggParamsHandlers } from './utils'; import { AggParamEditorProps } from '../agg_param_props'; import { DefaultEditorAggParams } from '../agg_params'; @@ -29,7 +29,6 @@ function SubAggParamEditor({ agg, aggParam, formIsTouched, - value, metricAggs, state, setValue, @@ -44,7 +43,7 @@ function SubAggParamEditor({ } else if (!agg.params.customMetric) { setValue(aggParam.makeAgg(agg)); } - }, [value, metricAggs]); + }, [metricAggs, agg, setValue, aggParam]); const { onAggTypeChange, setAggParamValue } = useSubAggParamsHandlers( agg, diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/sub_metric.tsx b/src/plugins/vis_default_editor/public/components/controls/sub_metric.tsx similarity index 96% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/sub_metric.tsx rename to src/plugins/vis_default_editor/public/components/controls/sub_metric.tsx index ead3f8bb00623..361eeba9abdbf 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/sub_metric.tsx +++ b/src/plugins/vis_default_editor/public/components/controls/sub_metric.tsx @@ -17,11 +17,12 @@ * under the License. */ -import React, { useEffect } from 'react'; +import React from 'react'; import { EuiFormLabel, EuiSpacer } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import { useMount } from 'react-use'; -import { AggParamType, IAggConfig, AggGroupNames } from '../../../../../../plugins/data/public'; +import { AggParamType, IAggConfig, AggGroupNames } from '../../../../data/public'; import { useSubAggParamsHandlers } from './utils'; import { AggParamEditorProps } from '../agg_param_props'; import { DefaultEditorAggParams } from '../agg_params'; @@ -48,13 +49,13 @@ function SubMetricParamEditor({ const aggTitle = type === 'customMetric' ? metricTitle : bucketTitle; const aggGroup = type === 'customMetric' ? AggGroupNames.Metrics : AggGroupNames.Buckets; - useEffect(() => { + useMount(() => { if (agg.params[type]) { setValue(agg.params[type]); } else { setValue(aggParam.makeAgg(agg)); } - }, []); + }); const { onAggTypeChange, setAggParamValue } = useSubAggParamsHandlers( agg, diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/switch.tsx b/src/plugins/vis_default_editor/public/components/controls/switch.tsx similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/switch.tsx rename to src/plugins/vis_default_editor/public/components/controls/switch.tsx diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/test_utils.ts b/src/plugins/vis_default_editor/public/components/controls/test_utils.ts similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/test_utils.ts rename to src/plugins/vis_default_editor/public/components/controls/test_utils.ts diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/time_interval.tsx b/src/plugins/vis_default_editor/public/components/controls/time_interval.tsx similarity index 98% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/time_interval.tsx rename to src/plugins/vis_default_editor/public/components/controls/time_interval.tsx index 971a62faf7d7c..4af41f67bc524 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/time_interval.tsx +++ b/src/plugins/vis_default_editor/public/components/controls/time_interval.tsx @@ -23,7 +23,7 @@ import { EuiFormRow, EuiIconTip, EuiComboBox, EuiComboBoxOptionOption } from '@e import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import { search, AggParamOption } from '../../../../../../plugins/data/public'; +import { search, AggParamOption } from '../../../../data/public'; import { AggParamEditorProps } from '../agg_param_props'; const { parseEsInterval, InvalidEsCalendarIntervalError } = search.aggs; @@ -161,7 +161,7 @@ function TimeIntervalParamEditor({ useEffect(() => { setValidity(isValid); - }, [isValid]); + }, [isValid, setValidity]); return ( { setValidity(isValid); - }, [isValid]); + }, [isValid, setValidity]); useEffect(() => { if (isFirstRun.current) { @@ -102,7 +102,7 @@ export function TopAggregateParamEditor({ if (filteredOptions.length === 1) { setValue(aggParam.options.find(opt => opt.value === filteredOptions[0].value)); } - }, [fieldType]); + }, [aggParam.options, fieldType, filteredOptions, setValue, value]); const handleChange = (event: React.ChangeEvent) => { if (event.target.value === emptyValue.value) { diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/top_field.tsx b/src/plugins/vis_default_editor/public/components/controls/top_field.tsx similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/top_field.tsx rename to src/plugins/vis_default_editor/public/components/controls/top_field.tsx diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/top_size.tsx b/src/plugins/vis_default_editor/public/components/controls/top_size.tsx similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/top_size.tsx rename to src/plugins/vis_default_editor/public/components/controls/top_size.tsx diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/top_sort_field.tsx b/src/plugins/vis_default_editor/public/components/controls/top_sort_field.tsx similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/top_sort_field.tsx rename to src/plugins/vis_default_editor/public/components/controls/top_sort_field.tsx diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/use_geocentroid.tsx b/src/plugins/vis_default_editor/public/components/controls/use_geocentroid.tsx similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/use_geocentroid.tsx rename to src/plugins/vis_default_editor/public/components/controls/use_geocentroid.tsx diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/utils/agg_utils.ts b/src/plugins/vis_default_editor/public/components/controls/utils/agg_utils.ts similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/utils/agg_utils.ts rename to src/plugins/vis_default_editor/public/components/controls/utils/agg_utils.ts diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/utils/index.ts b/src/plugins/vis_default_editor/public/components/controls/utils/index.ts similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/utils/index.ts rename to src/plugins/vis_default_editor/public/components/controls/utils/index.ts diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/utils/inline_comp_wrapper.tsx b/src/plugins/vis_default_editor/public/components/controls/utils/inline_comp_wrapper.tsx similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/utils/inline_comp_wrapper.tsx rename to src/plugins/vis_default_editor/public/components/controls/utils/inline_comp_wrapper.tsx diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/utils/strings/comma_separated_list.test.ts b/src/plugins/vis_default_editor/public/components/controls/utils/strings/comma_separated_list.test.ts similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/utils/strings/comma_separated_list.test.ts rename to src/plugins/vis_default_editor/public/components/controls/utils/strings/comma_separated_list.test.ts diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/utils/strings/comma_separated_list.ts b/src/plugins/vis_default_editor/public/components/controls/utils/strings/comma_separated_list.ts similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/utils/strings/comma_separated_list.ts rename to src/plugins/vis_default_editor/public/components/controls/utils/strings/comma_separated_list.ts diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/utils/strings/index.ts b/src/plugins/vis_default_editor/public/components/controls/utils/strings/index.ts similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/utils/strings/index.ts rename to src/plugins/vis_default_editor/public/components/controls/utils/strings/index.ts diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/utils/strings/prose.test.ts b/src/plugins/vis_default_editor/public/components/controls/utils/strings/prose.test.ts similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/utils/strings/prose.test.ts rename to src/plugins/vis_default_editor/public/components/controls/utils/strings/prose.test.ts diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/utils/strings/prose.ts b/src/plugins/vis_default_editor/public/components/controls/utils/strings/prose.ts similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/utils/strings/prose.ts rename to src/plugins/vis_default_editor/public/components/controls/utils/strings/prose.ts diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/utils/use_handlers.ts b/src/plugins/vis_default_editor/public/components/controls/utils/use_handlers.ts similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/controls/utils/use_handlers.ts rename to src/plugins/vis_default_editor/public/components/controls/utils/use_handlers.ts diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/controls.tsx b/src/plugins/vis_default_editor/public/components/sidebar/controls.tsx similarity index 98% rename from src/legacy/core_plugins/vis_default_editor/public/components/sidebar/controls.tsx rename to src/plugins/vis_default_editor/public/components/sidebar/controls.tsx index 18b445b4a26db..db9d7d9e3316a 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/controls.tsx +++ b/src/plugins/vis_default_editor/public/components/sidebar/controls.tsx @@ -30,7 +30,7 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; import { useDebounce } from 'react-use'; -import { Vis } from '../../../../../../plugins/visualizations/public'; +import { Vis } from 'src/plugins/visualizations/public'; import { discardChanges, EditorAction } from './state'; interface DefaultEditorControlsProps { diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/data_tab.tsx b/src/plugins/vis_default_editor/public/components/sidebar/data_tab.tsx similarity index 97% rename from src/legacy/core_plugins/vis_default_editor/public/components/sidebar/data_tab.tsx rename to src/plugins/vis_default_editor/public/components/sidebar/data_tab.tsx index 0c967723db8e7..0466c64541e23 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/data_tab.tsx +++ b/src/plugins/vis_default_editor/public/components/sidebar/data_tab.tsx @@ -26,7 +26,8 @@ import { IAggConfig, IMetricAggType, search, -} from '../../../../../../plugins/data/public'; + TimeRange, +} from '../../../../data/public'; import { DefaultEditorAggGroup } from '../agg_group'; import { EditorAction, @@ -39,7 +40,6 @@ import { } from './state'; import { AddSchema, ReorderAggs, DefaultEditorAggCommonProps } from '../agg_common_props'; import { ISchemas } from '../../schemas'; -import { TimeRange } from '../../../../../../plugins/data/public'; import { EditorVisState } from './state/reducers'; export interface DefaultEditorDataTabProps { diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/index.ts b/src/plugins/vis_default_editor/public/components/sidebar/index.ts similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/sidebar/index.ts rename to src/plugins/vis_default_editor/public/components/sidebar/index.ts diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/navbar.tsx b/src/plugins/vis_default_editor/public/components/sidebar/navbar.tsx similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/sidebar/navbar.tsx rename to src/plugins/vis_default_editor/public/components/sidebar/navbar.tsx diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/sidebar.tsx b/src/plugins/vis_default_editor/public/components/sidebar/sidebar.tsx similarity index 96% rename from src/legacy/core_plugins/vis_default_editor/public/components/sidebar/sidebar.tsx rename to src/plugins/vis_default_editor/public/components/sidebar/sidebar.tsx index b24486a12fd24..9dfeae1815d1a 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/sidebar.tsx +++ b/src/plugins/vis_default_editor/public/components/sidebar/sidebar.tsx @@ -23,16 +23,15 @@ import { i18n } from '@kbn/i18n'; import { keyCodes, EuiButtonIcon, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { EventEmitter } from 'events'; -import { Vis } from 'src/plugins/visualizations/public'; +import { Vis, PersistedState } from 'src/plugins/visualizations/public'; +import { SavedSearch } from 'src/plugins/discover/public'; +import { TimeRange } from 'src/plugins/data/public'; import { DefaultEditorNavBar, OptionTab } from './navbar'; import { DefaultEditorControls } from './controls'; import { setStateParamValue, useEditorReducer, useEditorFormState, discardChanges } from './state'; import { DefaultEditorAggCommonProps } from '../agg_common_props'; import { SidebarTitle } from './sidebar_title'; -import { PersistedState } from '../../../../../../plugins/visualizations/public'; -import { SavedSearch } from '../../../../../../plugins/discover/public'; import { Schema } from '../../schemas'; -import { TimeRange } from '../../../../../../plugins/data/public'; interface DefaultEditorSideBarProps { isCollapsed: boolean; diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/sidebar_title.tsx b/src/plugins/vis_default_editor/public/components/sidebar/sidebar_title.tsx similarity index 97% rename from src/legacy/core_plugins/vis_default_editor/public/components/sidebar/sidebar_title.tsx rename to src/plugins/vis_default_editor/public/components/sidebar/sidebar_title.tsx index fb63a598a4fae..c9f83e5b474a6 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/sidebar_title.tsx +++ b/src/plugins/vis_default_editor/public/components/sidebar/sidebar_title.tsx @@ -35,8 +35,8 @@ import { import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; -import { Vis } from '../../../../../../plugins/visualizations/public'; -import { SavedSearch } from '../../../../../../plugins/discover/public'; +import { Vis } from 'src/plugins/visualizations/public'; +import { SavedSearch } from 'src/plugins/discover/public'; interface LinkedSearchProps { savedSearch: SavedSearch; diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/state/actions.ts b/src/plugins/vis_default_editor/public/components/sidebar/state/actions.ts similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/sidebar/state/actions.ts rename to src/plugins/vis_default_editor/public/components/sidebar/state/actions.ts diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/state/constants.ts b/src/plugins/vis_default_editor/public/components/sidebar/state/constants.ts similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/sidebar/state/constants.ts rename to src/plugins/vis_default_editor/public/components/sidebar/state/constants.ts diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/state/editor_form_state.ts b/src/plugins/vis_default_editor/public/components/sidebar/state/editor_form_state.ts similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/sidebar/state/editor_form_state.ts rename to src/plugins/vis_default_editor/public/components/sidebar/state/editor_form_state.ts diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/state/index.ts b/src/plugins/vis_default_editor/public/components/sidebar/state/index.ts similarity index 96% rename from src/legacy/core_plugins/vis_default_editor/public/components/sidebar/state/index.ts rename to src/plugins/vis_default_editor/public/components/sidebar/state/index.ts index d39d6d07b32d2..1bfa100cbd0f7 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/state/index.ts +++ b/src/plugins/vis_default_editor/public/components/sidebar/state/index.ts @@ -24,7 +24,7 @@ import { Vis } from 'src/plugins/visualizations/public'; import { createEditorStateReducer, initEditorState, EditorVisState } from './reducers'; import { EditorStateActionTypes } from './constants'; import { EditorAction } from './actions'; -import { useKibana } from '../../../../../../../plugins/kibana_react/public'; +import { useKibana } from '../../../../../kibana_react/public'; import { VisDefaultEditorKibanaServices } from '../../../types'; export * from './editor_form_state'; diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/state/reducers.ts b/src/plugins/vis_default_editor/public/components/sidebar/state/reducers.ts similarity index 99% rename from src/legacy/core_plugins/vis_default_editor/public/components/sidebar/state/reducers.ts rename to src/plugins/vis_default_editor/public/components/sidebar/state/reducers.ts index b9f89cebd8bf3..4e7a2904584da 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/state/reducers.ts +++ b/src/plugins/vis_default_editor/public/components/sidebar/state/reducers.ts @@ -20,7 +20,7 @@ import { cloneDeep } from 'lodash'; import { Vis } from 'src/plugins/visualizations/public'; -import { AggGroupNames, DataPublicPluginStart } from '../../../../../../../plugins/data/public'; +import { AggGroupNames, DataPublicPluginStart } from '../../../../../data/public'; import { EditorStateActionTypes } from './constants'; import { getEnabledMetricAggsCount } from '../../agg_group_helper'; import { EditorAction } from './actions'; diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/utils/editor_config.ts b/src/plugins/vis_default_editor/public/components/utils/editor_config.ts similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/utils/editor_config.ts rename to src/plugins/vis_default_editor/public/components/utils/editor_config.ts diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/utils/index.ts b/src/plugins/vis_default_editor/public/components/utils/index.ts similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/components/utils/index.ts rename to src/plugins/vis_default_editor/public/components/utils/index.ts diff --git a/src/legacy/core_plugins/vis_default_editor/public/default_editor.tsx b/src/plugins/vis_default_editor/public/default_editor.tsx similarity index 94% rename from src/legacy/core_plugins/vis_default_editor/public/default_editor.tsx rename to src/plugins/vis_default_editor/public/default_editor.tsx index 899b9c1b5fd6e..f1963b94dcf95 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/default_editor.tsx +++ b/src/plugins/vis_default_editor/public/default_editor.tsx @@ -19,8 +19,8 @@ import React, { useEffect, useRef, useState, useCallback } from 'react'; -import { EditorRenderProps } from '../../kibana/public/visualize/np_ready/types'; -import { PanelsContainer, Panel } from '../../../../plugins/kibana_react/public'; +import { EditorRenderProps } from 'src/legacy/core_plugins/kibana/public/visualize/np_ready/types'; +import { PanelsContainer, Panel } from '../../kibana_react/public'; import './vis_type_agg_filter'; import { DefaultEditorSideBar } from './components/sidebar'; diff --git a/src/legacy/core_plugins/vis_default_editor/public/default_editor_controller.tsx b/src/plugins/vis_default_editor/public/default_editor_controller.tsx similarity index 92% rename from src/legacy/core_plugins/vis_default_editor/public/default_editor_controller.tsx rename to src/plugins/vis_default_editor/public/default_editor_controller.tsx index 58e67b5064da5..798da09f8e30b 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/default_editor_controller.tsx +++ b/src/plugins/vis_default_editor/public/default_editor_controller.tsx @@ -23,9 +23,9 @@ import { i18n } from '@kbn/i18n'; import { EventEmitter } from 'events'; import { EditorRenderProps } from 'src/legacy/core_plugins/kibana/public/visualize/np_ready/types'; -import { Vis, VisualizeEmbeddableContract } from '../../../../plugins/visualizations/public'; -import { Storage } from '../../../../plugins/kibana_utils/public'; -import { KibanaContextProvider } from '../../../../plugins/kibana_react/public'; +import { Vis, VisualizeEmbeddableContract } from 'src/plugins/visualizations/public'; +import { Storage } from '../../kibana_utils/public'; +import { KibanaContextProvider } from '../../kibana_react/public'; import { DefaultEditor } from './default_editor'; import { DefaultEditorDataTab, OptionTab } from './components/sidebar'; diff --git a/src/legacy/core_plugins/vis_default_editor/public/editor_size.ts b/src/plugins/vis_default_editor/public/editor_size.ts similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/editor_size.ts rename to src/plugins/vis_default_editor/public/editor_size.ts diff --git a/src/legacy/core_plugins/vis_default_editor/public/index.scss b/src/plugins/vis_default_editor/public/index.scss similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/index.scss rename to src/plugins/vis_default_editor/public/index.scss diff --git a/src/legacy/core_plugins/vis_default_editor/public/index.ts b/src/plugins/vis_default_editor/public/index.ts similarity index 97% rename from src/legacy/core_plugins/vis_default_editor/public/index.ts rename to src/plugins/vis_default_editor/public/index.ts index 156d50f451b57..6c58c6df26b00 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/index.ts +++ b/src/plugins/vis_default_editor/public/index.ts @@ -17,6 +17,8 @@ * under the License. */ +import './index.scss'; + export { DefaultEditorController } from './default_editor_controller'; export { useValidation } from './components/controls/utils'; export { RangesParamEditor, RangeValues } from './components/controls/ranges'; diff --git a/src/legacy/core_plugins/vis_default_editor/public/schemas.ts b/src/plugins/vis_default_editor/public/schemas.ts similarity index 96% rename from src/legacy/core_plugins/vis_default_editor/public/schemas.ts rename to src/plugins/vis_default_editor/public/schemas.ts index 4e632da44afc0..05ba5fa9c9419 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/schemas.ts +++ b/src/plugins/vis_default_editor/public/schemas.ts @@ -21,7 +21,7 @@ import _, { defaults } from 'lodash'; import { Optional } from '@kbn/utility-types'; -import { AggGroupNames, AggParam, IAggGroupNames } from '../../../../plugins/data/public'; +import { AggGroupNames, AggParam, IAggGroupNames } from '../../data/public'; export interface ISchemas { [AggGroupNames.Buckets]: Schema[]; diff --git a/src/legacy/core_plugins/vis_default_editor/public/types.ts b/src/plugins/vis_default_editor/public/types.ts similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/types.ts rename to src/plugins/vis_default_editor/public/types.ts diff --git a/src/legacy/core_plugins/vis_default_editor/public/utils.test.ts b/src/plugins/vis_default_editor/public/utils.test.ts similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/utils.test.ts rename to src/plugins/vis_default_editor/public/utils.test.ts diff --git a/src/legacy/core_plugins/vis_default_editor/public/utils.ts b/src/plugins/vis_default_editor/public/utils.ts similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/utils.ts rename to src/plugins/vis_default_editor/public/utils.ts diff --git a/src/legacy/core_plugins/vis_default_editor/public/vis_options_props.tsx b/src/plugins/vis_default_editor/public/vis_options_props.tsx similarity index 100% rename from src/legacy/core_plugins/vis_default_editor/public/vis_options_props.tsx rename to src/plugins/vis_default_editor/public/vis_options_props.tsx diff --git a/src/legacy/core_plugins/vis_default_editor/public/vis_type_agg_filter.ts b/src/plugins/vis_default_editor/public/vis_type_agg_filter.ts similarity index 97% rename from src/legacy/core_plugins/vis_default_editor/public/vis_type_agg_filter.ts rename to src/plugins/vis_default_editor/public/vis_type_agg_filter.ts index 3ff212c43e6e8..bf5661f42a9f5 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/vis_type_agg_filter.ts +++ b/src/plugins/vis_default_editor/public/vis_type_agg_filter.ts @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import { IAggType, IAggConfig, IndexPattern, search } from '../../../../plugins/data/public'; +import { IAggType, IAggConfig, IndexPattern, search } from '../../data/public'; const { aggTypeFilters, propFilter } = search.aggs; const filterByName = propFilter('name'); diff --git a/test/plugin_functional/plugins/kbn_tp_custom_visualizations/public/self_changing_vis/self_changing_editor.tsx b/test/plugin_functional/plugins/kbn_tp_custom_visualizations/public/self_changing_vis/self_changing_editor.tsx index d3f66d708603c..6c430e34d5e29 100644 --- a/test/plugin_functional/plugins/kbn_tp_custom_visualizations/public/self_changing_vis/self_changing_editor.tsx +++ b/test/plugin_functional/plugins/kbn_tp_custom_visualizations/public/self_changing_vis/self_changing_editor.tsx @@ -20,7 +20,7 @@ import React from 'react'; import { EuiFieldNumber, EuiFormRow } from '@elastic/eui'; -import { VisOptionsProps } from '../../../../../../src/legacy/core_plugins/vis_default_editor/public/vis_options_props'; +import { VisOptionsProps } from 'src/plugins/vis_default_editor/public/vis_options_props'; interface CounterParams { counter: number; From 3d6fd68eb2117290451abe223afd5de19a55cb19 Mon Sep 17 00:00:00 2001 From: Maryia Lapata Date: Wed, 8 Apr 2020 12:48:41 +0300 Subject: [PATCH 02/40] Get rid of ui/i18n in Discover (#62799) --- .../public/discover/get_inner_angular.ts | 1 - .../kibana/public/discover/kibana_services.ts | 2 - .../components/action_bar/action_bar.tsx | 146 ++++---- .../action_bar/action_bar_directive.ts | 4 +- .../np_ready/angular/directives/index.js | 10 +- .../np_ready/angular/directives/no_results.js | 46 +-- .../angular/directives/uninitialized.tsx | 70 ++-- .../public/discover/np_ready/angular/doc.ts | 4 +- .../doc_table/components/pager/index.ts | 5 +- .../components/pager/tool_bar_pager_text.tsx | 18 +- .../doc_table/components/table_header.ts | 4 +- .../discover/np_ready/components/doc/doc.tsx | 146 ++++---- .../components/fetch_error/fetch_error.tsx | 32 +- .../components/sidebar/discover_sidebar.tsx | 316 +++++++++--------- .../sidebar/discover_sidebar_directive.ts | 3 +- 15 files changed, 412 insertions(+), 395 deletions(-) diff --git a/src/legacy/core_plugins/kibana/public/discover/get_inner_angular.ts b/src/legacy/core_plugins/kibana/public/discover/get_inner_angular.ts index 607d79b81618e..6ccbc13aeeb57 100644 --- a/src/legacy/core_plugins/kibana/public/discover/get_inner_angular.ts +++ b/src/legacy/core_plugins/kibana/public/discover/get_inner_angular.ts @@ -201,7 +201,6 @@ function createDocTableModule() { .directive('docTable', createDocTableDirective) .directive('kbnTableHeader', createTableHeaderDirective) .directive('toolBarPagerText', createToolBarPagerTextDirective) - .directive('toolBarPagerText', createToolBarPagerTextDirective) .directive('kbnTableRow', createTableRowDirective) .directive('toolBarPagerButtons', createToolBarPagerButtonsDirective) .directive('kbnInfiniteScroll', createInfiniteScrollDirective) diff --git a/src/legacy/core_plugins/kibana/public/discover/kibana_services.ts b/src/legacy/core_plugins/kibana/public/discover/kibana_services.ts index 55f369eaecd2c..e6421142f6666 100644 --- a/src/legacy/core_plugins/kibana/public/discover/kibana_services.ts +++ b/src/legacy/core_plugins/kibana/public/discover/kibana_services.ts @@ -50,8 +50,6 @@ export const [getUrlTracker, setUrlTracker] = createGetterSetter<{ setTrackedUrl: (url: string) => void; }>('urlTracker'); -// EXPORT legacy static dependencies, should be migrated when available in a new version; -export { wrapInI18nContext } from 'ui/i18n'; import { search } from '../../../../../plugins/data/public'; import { createGetterSetter } from '../../../../../plugins/kibana_utils/common'; export const { getRequestInspectorStats, getResponseInspectorStats, tabifyAggResponse } = search; diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/context/components/action_bar/action_bar.tsx b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/context/components/action_bar/action_bar.tsx index 57ad8e0b1040f..8fcfcba08955c 100644 --- a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/context/components/action_bar/action_bar.tsx +++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/context/components/action_bar/action_bar.tsx @@ -18,7 +18,7 @@ */ import React, { useState } from 'react'; import { i18n } from '@kbn/i18n'; -import { FormattedMessage } from '@kbn/i18n/react'; +import { FormattedMessage, I18nProvider } from '@kbn/i18n/react'; import { EuiButtonEmpty, EuiFieldNumber, @@ -88,77 +88,83 @@ export function ActionBar({ }; return ( -
- {isSuccessor && } - {isSuccessor && showWarning && } - {isSuccessor && showWarning && } - - - { - const value = newDocCount + defaultStepSize; - if (isValid(value)) { - setNewDocCount(value); - onChangeCount(value); - } - }} - flush="right" - > - - - - - - { - setNewDocCount(ev.target.valueAsNumber); - }} - onBlur={() => { - if (newDocCount !== docCount && isValid(newDocCount)) { - onChangeCount(newDocCount); + + + {isSuccessor && } + {isSuccessor && showWarning && ( + + )} + {isSuccessor && showWarning && } + + + { + const value = newDocCount + defaultStepSize; + if (isValid(value)) { + setNewDocCount(value); + onChangeCount(value); } }} - type="number" - value={newDocCount >= 0 ? newDocCount : ''} - /> - - - - - {isSuccessor ? ( - - ) : ( - + + + + + + { + setNewDocCount(ev.target.valueAsNumber); + }} + onBlur={() => { + if (newDocCount !== docCount && isValid(newDocCount)) { + onChangeCount(newDocCount); + } + }} + type="number" + value={newDocCount >= 0 ? newDocCount : ''} /> - )} - - - - {!isSuccessor && showWarning && } - {!isSuccessor && } - +
+
+ + + {isSuccessor ? ( + + ) : ( + + )} + + + + {!isSuccessor && showWarning && ( + + )} + {!isSuccessor && } + + ); } diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/context/components/action_bar/action_bar_directive.ts b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/context/components/action_bar/action_bar_directive.ts index 697b039adde81..b705b4e4faeb5 100644 --- a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/context/components/action_bar/action_bar_directive.ts +++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/context/components/action_bar/action_bar_directive.ts @@ -16,9 +16,9 @@ * specific language governing permissions and limitations * under the License. */ -import { getAngularModule, wrapInI18nContext } from '../../../../../kibana_services'; +import { getAngularModule } from '../../../../../kibana_services'; import { ActionBar } from './action_bar'; getAngularModule().directive('contextActionBar', function(reactDirective: any) { - return reactDirective(wrapInI18nContext(ActionBar)); + return reactDirective(ActionBar); }); diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/index.js b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/index.js index 5482258e06564..5a999235bf9a5 100644 --- a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/index.js +++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/index.js @@ -20,16 +20,12 @@ import { DiscoverNoResults } from './no_results'; import { DiscoverUninitialized } from './uninitialized'; import { DiscoverHistogram } from './histogram'; -import { getAngularModule, wrapInI18nContext } from '../../../kibana_services'; +import { getAngularModule } from '../../../kibana_services'; const app = getAngularModule(); -app.directive('discoverNoResults', reactDirective => - reactDirective(wrapInI18nContext(DiscoverNoResults)) -); +app.directive('discoverNoResults', reactDirective => reactDirective(DiscoverNoResults)); -app.directive('discoverUninitialized', reactDirective => - reactDirective(wrapInI18nContext(DiscoverUninitialized)) -); +app.directive('discoverUninitialized', reactDirective => reactDirective(DiscoverUninitialized)); app.directive('discoverHistogram', reactDirective => reactDirective(DiscoverHistogram)); diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/no_results.js b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/no_results.js index ba02068590c14..ad81d5252a25c 100644 --- a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/no_results.js +++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/no_results.js @@ -18,7 +18,7 @@ */ import React, { Component, Fragment } from 'react'; -import { FormattedMessage } from '@kbn/i18n/react'; +import { FormattedMessage, I18nProvider } from '@kbn/i18n/react'; import PropTypes from 'prop-types'; import { @@ -247,29 +247,31 @@ export class DiscoverNoResults extends Component { } return ( - - + + + - - - - } - color="warning" - iconType="help" - data-test-subj="discoverNoResults" - /> + + + + } + color="warning" + iconType="help" + data-test-subj="discoverNoResults" + /> - {shardFailuresMessage} - {timeFieldMessage} - {luceneQueryMessage} - - - + {shardFailuresMessage} + {timeFieldMessage} + {luceneQueryMessage} + + + + ); } } diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/uninitialized.tsx b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/uninitialized.tsx index f40865800098e..b308607bbfbb0 100644 --- a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/uninitialized.tsx +++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/uninitialized.tsx @@ -18,7 +18,7 @@ */ import React from 'react'; -import { FormattedMessage } from '@kbn/i18n/react'; +import { FormattedMessage, I18nProvider } from '@kbn/i18n/react'; import { EuiButton, EuiEmptyPrompt, EuiPage, EuiPageBody, EuiPageContent } from '@elastic/eui'; @@ -28,38 +28,40 @@ interface Props { export const DiscoverUninitialized = ({ onRefresh }: Props) => { return ( - - - - - - - } - body={ -

- -

- } - actions={ - - - - } - /> -
-
-
+ + + + + + + + } + body={ +

+ +

+ } + actions={ + + + + } + /> +
+
+
+
); }; diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc.ts b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc.ts index 459dcfb30d17b..092e3c79b1007 100644 --- a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc.ts +++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc.ts @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import { getAngularModule, wrapInI18nContext, getServices } from '../../kibana_services'; +import { getAngularModule, getServices } from '../../kibana_services'; // @ts-ignore import { getRootBreadcrumbs } from '../helpers/breadcrumbs'; import html from './doc.html'; @@ -30,7 +30,7 @@ const { timefilter } = getServices(); const app = getAngularModule(); app.directive('discoverDoc', function(reactDirective: any) { return reactDirective( - wrapInI18nContext(Doc), + Doc, [ ['id', { watchDepth: 'value' }], ['index', { watchDepth: 'value' }], diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc_table/components/pager/index.ts b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc_table/components/pager/index.ts index f21f3b17c6955..7e155a6b82ca0 100644 --- a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc_table/components/pager/index.ts +++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc_table/components/pager/index.ts @@ -16,14 +16,13 @@ * specific language governing permissions and limitations * under the License. */ -import { wrapInI18nContext } from '../../../../../kibana_services'; import { ToolBarPagerText } from './tool_bar_pager_text'; import { ToolBarPagerButtons } from './tool_bar_pager_buttons'; export function createToolBarPagerTextDirective(reactDirective: any) { - return reactDirective(wrapInI18nContext(ToolBarPagerText)); + return reactDirective(ToolBarPagerText); } export function createToolBarPagerButtonsDirective(reactDirective: any) { - return reactDirective(wrapInI18nContext(ToolBarPagerButtons)); + return reactDirective(ToolBarPagerButtons); } diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc_table/components/pager/tool_bar_pager_text.tsx b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc_table/components/pager/tool_bar_pager_text.tsx index 608dadd36b4b9..84338d817c86b 100644 --- a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc_table/components/pager/tool_bar_pager_text.tsx +++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc_table/components/pager/tool_bar_pager_text.tsx @@ -17,7 +17,7 @@ * under the License. */ import React from 'react'; -import { FormattedMessage } from '@kbn/i18n/react'; +import { FormattedMessage, I18nProvider } from '@kbn/i18n/react'; interface Props { startItem: number; @@ -27,12 +27,14 @@ interface Props { export function ToolBarPagerText({ startItem, endItem, totalItems }: Props) { return ( -
- -
+ +
+ +
+
); } diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc_table/components/table_header.ts b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc_table/components/table_header.ts index 84d865fd22a9a..5e7ad6a1d1ea0 100644 --- a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc_table/components/table_header.ts +++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc_table/components/table_header.ts @@ -17,13 +17,13 @@ * under the License. */ import { TableHeader } from './table_header/table_header'; -import { wrapInI18nContext, getServices } from '../../../../kibana_services'; +import { getServices } from '../../../../kibana_services'; export function createTableHeaderDirective(reactDirective: any) { const { uiSettings: config } = getServices(); return reactDirective( - wrapInI18nContext(TableHeader), + TableHeader, [ ['columns', { watchDepth: 'collection' }], ['hideTimeColumn', { watchDepth: 'value' }], diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/doc/doc.tsx b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/doc/doc.tsx index 28a17dbdb67b7..f3ceaef57d700 100644 --- a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/doc/doc.tsx +++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/doc/doc.tsx @@ -17,7 +17,7 @@ * under the License. */ import React from 'react'; -import { FormattedMessage } from '@kbn/i18n/react'; +import { FormattedMessage, I18nProvider } from '@kbn/i18n/react'; import { EuiCallOut, EuiLink, EuiLoadingSpinner, EuiPageContent } from '@elastic/eui'; import { IndexPatternsContract } from 'src/plugins/data/public'; import { ElasticRequestState, useEsDocSearch } from './use_es_doc_search'; @@ -65,83 +65,85 @@ export function Doc(props: DocProps) { const [reqState, hit, indexPattern] = useEsDocSearch(props); return ( - - {reqState === ElasticRequestState.NotFoundIndexPattern && ( - - } - /> - )} - {reqState === ElasticRequestState.NotFound && ( - - } - > - + + {reqState === ElasticRequestState.NotFoundIndexPattern && ( + + } /> - - )} - - {reqState === ElasticRequestState.Error && ( - + } + > - } - > - {' '} - + )} + + {reqState === ElasticRequestState.Error && ( + + } > - - - )} + id="kbn.doc.somethingWentWrongDescription" + defaultMessage="{indexName} is missing." + values={{ indexName: props.index }} + />{' '} + + + + + )} - {reqState === ElasticRequestState.Loading && ( - - {' '} - - - )} + {reqState === ElasticRequestState.Loading && ( + + {' '} + + + )} - {reqState === ElasticRequestState.Found && hit !== null && indexPattern && ( -
- -
- )} -
+ {reqState === ElasticRequestState.Found && hit !== null && indexPattern && ( +
+ +
+ )} + + ); } diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/fetch_error/fetch_error.tsx b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/fetch_error/fetch_error.tsx index 1aad7e953b8de..f8fc966dec351 100644 --- a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/fetch_error/fetch_error.tsx +++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/fetch_error/fetch_error.tsx @@ -17,9 +17,9 @@ * under the License. */ import React, { Fragment } from 'react'; -import { FormattedMessage } from '@kbn/i18n/react'; +import { FormattedMessage, I18nProvider } from '@kbn/i18n/react'; import { EuiFlexGroup, EuiFlexItem, EuiCallOut, EuiCodeBlock, EuiSpacer } from '@elastic/eui'; -import { getAngularModule, wrapInI18nContext, getServices } from '../../../kibana_services'; +import { getAngularModule, getServices } from '../../../kibana_services'; interface Props { fetchError: { @@ -72,26 +72,28 @@ const DiscoverFetchError = ({ fetchError }: Props) => { } return ( - - + + + - - - - {body} + + + + {body} - {fetchError.error} - - - + {fetchError.error} + + + - - + + + ); }; export function createFetchErrorDirective(reactDirective: any) { - return reactDirective(wrapInI18nContext(DiscoverFetchError)); + return reactDirective(DiscoverFetchError); } getAngularModule().directive('discoverFetchError', createFetchErrorDirective); diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/discover_sidebar.tsx b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/discover_sidebar.tsx index 5984df9c76e61..0adda0e484843 100644 --- a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/discover_sidebar.tsx +++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/discover_sidebar.tsx @@ -20,7 +20,7 @@ import React, { useCallback, useEffect, useState, useMemo } from 'react'; import { i18n } from '@kbn/i18n'; import { EuiButtonIcon, EuiTitle } from '@elastic/eui'; import { sortBy } from 'lodash'; -import { FormattedMessage } from '@kbn/i18n/react'; +import { FormattedMessage, I18nProvider } from '@kbn/i18n/react'; import { DiscoverField } from './discover_field'; import { DiscoverIndexPattern } from './discover_index_pattern'; import { DiscoverFieldSearch } from './discover_field_search'; @@ -162,165 +162,175 @@ export function DiscoverSidebar({ } return ( -
- o.attributes.title)} - /> -
-
- - -
-
- {fields.length > 0 && ( - <> - -

- -

-
-
    - {selectedFields.map((field: IndexPatternField, idx: number) => { - return ( -
  • - -
  • - ); - })} -
-
- + +
+ o.attributes.title)} + /> +
+
+ + +
+
+ {fields.length > 0 && ( + <> +

-
- setShowFields(!showFields)} - aria-label={ - showFields - ? i18n.translate( - 'kbn.discover.fieldChooser.filter.indexAndFieldsSectionHideAriaLabel', - { - defaultMessage: 'Hide fields', - } - ) - : i18n.translate( - 'kbn.discover.fieldChooser.filter.indexAndFieldsSectionShowAriaLabel', - { - defaultMessage: 'Show fields', - } - ) - } - /> +
    + {selectedFields.map((field: IndexPatternField, idx: number) => { + return ( +
  • + +
  • + ); + })} +
+
+ +

+ +

+
+
+ setShowFields(!showFields)} + aria-label={ + showFields + ? i18n.translate( + 'kbn.discover.fieldChooser.filter.indexAndFieldsSectionHideAriaLabel', + { + defaultMessage: 'Hide fields', + } + ) + : i18n.translate( + 'kbn.discover.fieldChooser.filter.indexAndFieldsSectionShowAriaLabel', + { + defaultMessage: 'Show fields', + } + ) + } + /> +
+ + )} + {popularFields.length > 0 && ( +
+ + + +
    + {popularFields.map((field: IndexPatternField, idx: number) => { + return ( +
  • + +
  • + ); + })} +
- - )} - {popularFields.length > 0 && ( -
- - - -
    - {popularFields.map((field: IndexPatternField, idx: number) => { - return ( -
  • - -
  • - ); - })} -
-
- )} + )} -
    - {unpopularFields.map((field: IndexPatternField, idx: number) => { - return ( -
  • - -
  • - ); - })} -
-
-
+
    + {unpopularFields.map((field: IndexPatternField, idx: number) => { + return ( +
  • + +
  • + ); + })} +
+
+
+ ); } diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/discover_sidebar_directive.ts b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/discover_sidebar_directive.ts index 9dcb459f83613..624ec0f757894 100644 --- a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/discover_sidebar_directive.ts +++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/sidebar/discover_sidebar_directive.ts @@ -16,11 +16,10 @@ * specific language governing permissions and limitations * under the License. */ -import { wrapInI18nContext } from '../../../kibana_services'; import { DiscoverSidebar } from './discover_sidebar'; export function createDiscoverSidebarDirective(reactDirective: any) { - return reactDirective(wrapInI18nContext(DiscoverSidebar), [ + return reactDirective(DiscoverSidebar, [ ['columns', { watchDepth: 'reference' }], ['fieldCounts', { watchDepth: 'reference' }], ['hits', { watchDepth: 'reference' }], From cc9c4113b2b889044ea216b3c8734244ec058420 Mon Sep 17 00:00:00 2001 From: Larry Gregory Date: Wed, 8 Apr 2020 07:15:31 -0400 Subject: [PATCH 03/40] Document sub-feature privileges (#62335) * documenting sub-feature privileges * Apply suggestions from code review Co-Authored-By: gchaps <33642766+gchaps@users.noreply.github.com> * address PR feedback Co-authored-by: gchaps <33642766+gchaps@users.noreply.github.com> --- ...pment-plugin-feature-registration.asciidoc | 82 +++++++++++++++++- .../authorization/kibana-privileges.asciidoc | 7 +- .../images/assign_feature_privilege.png | Bin 507672 -> 651165 bytes 3 files changed, 87 insertions(+), 2 deletions(-) diff --git a/docs/developer/plugin/development-plugin-feature-registration.asciidoc b/docs/developer/plugin/development-plugin-feature-registration.asciidoc index ca61e5309ce85..4702204196bf2 100644 --- a/docs/developer/plugin/development-plugin-feature-registration.asciidoc +++ b/docs/developer/plugin/development-plugin-feature-registration.asciidoc @@ -45,10 +45,15 @@ Registering a feature consists of the following fields. For more information, co |An array of applications this feature enables. Typically, all of your plugin's apps (from `uiExports`) will be included here. |`privileges` (required) -|{repo}blob/{branch}/x-pack/plugins/features/server/feature.ts[`FeatureWithAllOrReadPrivileges`]. +|{repo}blob/{branch}/x-pack/plugins/features/common/feature.ts[`FeatureConfig`]. |See <> and <> |The set of privileges this feature requires to function. +|`subFeatures` (optional) +|{repo}blob/{branch}/x-pack/plugins/features/common/feature.ts[`FeatureConfig`]. +|See <> +|The set of subfeatures that enables finer access control than the `all` and `read` feature privileges. These options are only available in the Gold subscription level and higher. + |`icon` |`string` |"discoverApp" @@ -192,3 +197,78 @@ server.route({ } }); ----------- + +[[example-3-discover]] +==== Example 3: Discover + +Discover takes advantage of subfeature privileges to allow fine-grained access control. In this example, +a single "Create Short URLs" subfeature privilege is defined, which allows users to grant access to this feature without having to grant the `all` privilege to Discover. In other words, you can grant `read` access to Discover, and also grant the ability to create short URLs. + +["source","javascript"] +----------- +init(server) { + const xpackMainPlugin = server.plugins.xpack_main; + xpackMainPlugin.registerFeature({ + { + id: 'discover', + name: i18n.translate('xpack.features.discoverFeatureName', { + defaultMessage: 'Discover', + }), + order: 100, + icon: 'discoverApp', + navLinkId: 'kibana:discover', + app: ['kibana'], + catalogue: ['discover'], + privileges: { + all: { + app: ['kibana'], + catalogue: ['discover'], + savedObject: { + all: ['search', 'query'], + read: ['index-pattern'], + }, + ui: ['show', 'save', 'saveQuery'], + }, + read: { + app: ['kibana'], + catalogue: ['discover'], + savedObject: { + all: [], + read: ['index-pattern', 'search', 'query'], + }, + ui: ['show'], + }, + }, + subFeatures: [ + { + name: i18n.translate('xpack.features.ossFeatures.discoverShortUrlSubFeatureName', { + defaultMessage: 'Short URLs', + }), + privilegeGroups: [ + { + groupType: 'independent', + privileges: [ + { + id: 'url_create', + name: i18n.translate( + 'xpack.features.ossFeatures.discoverCreateShortUrlPrivilegeName', + { + defaultMessage: 'Create Short URLs', + } + ), + includeIn: 'all', + savedObject: { + all: ['url'], + read: [], + }, + ui: ['createShortUrl'], + }, + ], + }, + ], + }, + ], + } + }); +} +----------- diff --git a/docs/user/security/authorization/kibana-privileges.asciidoc b/docs/user/security/authorization/kibana-privileges.asciidoc index 6a0b7cefab018..21fcb9bdccb87 100644 --- a/docs/user/security/authorization/kibana-privileges.asciidoc +++ b/docs/user/security/authorization/kibana-privileges.asciidoc @@ -43,6 +43,10 @@ Assigning a feature privilege grants access to a specific feature. `all`:: Grants full read-write access. `read`:: Grants read-only access. +===== Sub-feature privileges +Some features allow for finer access control than the `all` and `read` privileges. +This additional level of control is available in the Gold subscription level and higher. + ===== Assigning feature privileges From the role management screen: @@ -62,7 +66,8 @@ PUT /api/security/role/my_kibana_role { "base": [], "feature": { - "dashboard": ["all"] + "visualize": ["all"], + "dashboard": ["read", "url_create"] }, "spaces": ["marketing"] } diff --git a/docs/user/security/images/assign_feature_privilege.png b/docs/user/security/images/assign_feature_privilege.png index e7d000d4554ad3e80b4eecc46bd5cfc2c67c1d54..26fbbf20b39ad665a3ab5d2dc7ab3f65c8922ae4 100644 GIT binary patch literal 651165 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

*8;$-fZ*AFtK2 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

d0!vkfZsAcqo2DY6BJ?AR(5Q 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

Hk7@ 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 E0CRj)@&Et; literal 507672 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

%i{%dnVwf(}40 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

O7+eIK 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

EiIiA&MailnCjO( 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%0A4V zc{)Ele_7gd=tyCq1@TJfv{(%`J!%vlUy_UYI61TrWceIJBuZKdP>HrYoq{C|m&bFnH7807k?vWai)F&?vkL{tm$`e4?^`9$^eLX~T#QI9lpUU1$RLDY z)5IH!iI;~AlWx+N@+b63P-Qf6Zse23Bi4Rph~ws-Utr_!m|=+!vxqym$~;}Q}QcoUt(_H zy{_gkfWu~kx(0LG5&FX#puK^#-|S%9sAL~n7z>9fcFfxO;3e@-Atz@8_*2mMGYUOh z&X*SjsZoEc4nL+RxGVr}>Q8n1GC^dJqWN81E_ZdVpOWs&1) z=q;$;Qo{v0te0`j|XX60I(o4;^1g=ANpXM^+-b{6Dk~Gu_HB zTl^H5?{6VYod=MmVhW3k;X_PPC4t;uxH6_QtmWj2;Z@VOBWtQZD6e_Cxyf5StAM*2 zHZoBf0t8P4gVsSBHWEiS5=ZK2uuK{X+DZy^ZR|md6dZpJyqN)nO(HZmfQ_oc&>3nM zGK=Sc`)XS~%;zX<{f1bFd)*0>g4$NIGwyHSzEv$RaSd0)2ZlqeE$giS%cH-Vpk?^Q zI*~aL%}BGL@j1{_KZ`rhME4?yf=%N*Y*9r#{c?g?>FB%H*FSWe1bYw_)is5<=+g;i zg7Y}4b+1U2Mj@p3{H@uVi<}!7(5wIAg8t#9X@%Gc9=>{a0>T6T^zdAd}-NF6P?nYhor9HJ{>wqL&*g z#Pr1n_+{xK3~p75#V3)4^#bL0ctQlk~)H%|Zf(SC69Vk2lF z0o0Q)@+`q5=psSY%_gZrhG)oF`v7QDum78ddK&|G4cE+V?of#mA&6aXrMr_cwRL8! zT!R$tQ^!g>Z!2Bs6w7|6P1elttQEhAQ^z|!UN0bV!M?#)-;GZcWM<0TTy}Wp9AX(_0$TT@<7HZaUk;gvF^q6w2OCC1`=5ylp2)vf~r?&@C0OMpLXr2BHF^&wN?St&{% z9yDih*Bz7^blVE^BC2z)@_1iwZ&qJtzS|%Z3kAir{{H4lZAxlJweXq%E_`L8<3p9d z6DwMRzKtP63hSxQ-4ErakR*wVa}^#u+x_8m2WdUu0rLkyF}*FQ+IoKe`jbT(G84%; zznfFIGVFaI+OgUyQl^bQ7o?@a_=dRG?TFGPp7ZCY54e41#a7K9zg(aIMQ5Ec+8R+a zw(Ro-?XkmC#f3@?Af*`EMdt$l9xbXc+2{ZncHqUl_wQH$Gq<24`R>Ub_U4_mfwtHC znoquam~;MDZTeS4JIq7!8Hut1-B=pQkI&p6~;4 z|IZBl3m2Lg`p|y-e24LHkC)?_xh!b-EB;f|M?dUMsVkjPmx3YR0g6uTj3Vg({Smzm z|1q3y-w`?~o!e)i_KQh0?OQ;93#D-|@5*oiJe9ppb%snc^WI>0)So?=jlLE7E^ISy z&W<#My&Qa;Wc^|!&S-37*1U1|al(m-yMdLan7Zy96`?*=_(~12dDH?PD*L|EtycwU z2Wi3li?j6aFYC`TqC7Ni+^*|GxL1OM&q;{+Xf-lcB}Sbu{JCNu8s$2OvW<>B*M$!k zmva@JzEAtX8t9d(l{`N`1Oec;9)<4M&3WR3TLpg9bo92*S{~^ICy9~v-@ow3*8C%$ ztv_~XR%cqty`rixiY7Q^?cCe&TjFk53wuM{G0)__pDYOu&+4DX3Ap&reA}dCg2{6u z(M}xojBaesPY%aD1U}RuSDh5gL;;92CGo?a;>N|5A3xHxb#`9Na?EW6c>y%Ktc6J8 zR|bIa;P~0k!at!|f0+J1Jga)sA=Hy<8In>`pxKSOiV7Z6fbLYn`nGqk*sY=gkiV3e zk27s&TMLl0>gGz?*{ zJt&>u9-eFqzPqu#E@6x;9<&j`-u9Pe^iYD0ZsnA3GNM5pf>Fs+Blg=q)YwB{_VgQ%BOxLL+zD~ObVy%45Q8twH!<_S z^+*nw`*3zP*~|k89^>|q0*IJpY^qestkvVLw=Dc&`~KyWzrU1zKo=GHv>3#AUNj&3 zkl9~C3i)kF32*kH8e#>adq8#-F9st*|*{l;Ly&KY@NT$<}yGS@dfDRi0B?J zFv)A`{_|b@q6sO;yW*0@Q5sX9HL(^R^$^8keya3h`|ZVf^jymLOzLza6fyxDLY!ea@cxxHvc{=|jANWI9>3PtXG4qwjk) zJ@Xx9WHD6N+O+(lA8J8KEVdf&+?~j_B)s>n^?JiTc<=`9uGfRl9O^<10 zh7grroZT$O%F=s72x+%M9zP1XaKFBkZro-fDzX}5JYXeEVJ(ShG~cDOxgSZT!_W>w zf1d^ZWqW_9$S?1~9!qf;Ihf4KH`DJwze^DYU=Er=0VdRG@t7 zy_Fd;>}XaTf#3^P?qm~|7N)b~N3NOk)Fm3dBY?aTfvpa~$^ZZu2^o>qM}8?h{EZm1 zXs9<}gp7!qq(R00jJK_oyd~GG_nYH>vtNEAT$E|Xsb0@~_G+PX(z6J#z`3>jq?4bb zDkU9=+5U>8s$&rJ=jr~#K+F8GG<6PCAG3MU!|IMqTgd=owwFq={{u`P1;3{7T}xw6 zb3hJOY2n*mWcz~^SNYNMnN_Dv)0!OZPK{&pV=46Rn`ErV8N5RI*Mxm~Cd*UO+cXXSw@Mtx+%x1GiMUz&vZnZ>jMgJj zl*bK$*IuKdMMtye5`Rk&{4?qPllN?m=ov*Gi;0SB)-#`mSi4$su-rQY@DthyZPz?v zOWaE_Jw=lyUhgly1=X)tsbaSOyIbHFWdiJa)o%^;zTph-A^(sI7R_9;r9`9Y3$0%_ z{ty51H@`S00pti?pJ@UA&ENfW6#n?rwbKA${ME4Y|E;M0F~j{m9-zZ(-+H$G=Qs54 zNBNh(jlT|ra`!h)f8Njkm&L2wmeVn!5>rkSf3i*dae05UE61J!DN)Yl_dk0||MrQ0 zT}r*np~-~)hoj4$UgBu{(Ko4ZHJysFwVCIZ21pHR;yZ=I1vT9yt7d`g?vD!qR9Qw{DEP7< zKm(Y{=1Qr|mUF(odhz1_^dyn>o1Dk62Pn&ppR)gh^8QhmrAyV_E%N1LE6m*?`4v^S zf`dEjnWee^|6{@q3Hj`8@#sX>I`DA5c=4S`S{~A`lW{S>X}Ef#+M}$hOmrF+zha$8 zj8x_x)ZQ9)3j9?Y{*#5XKUtbr*J9i!7vF+5JNIL~0C&5Khg)T;4YbjQR7bf>t-l>N zKxG>W_7hm(NN}@cz{mNV`1(Bz{;yV8FTxq(Y?dWgQBL*LN1T1%^NdFP{FkyCe5URP zHIE~(mh(#=-P?A@JdrN_4yrl{{~usVNR!?RJtYa*eT-bZWwU7%%k+s&S^0HhcJ$AN z#=p5BZRu#-`{lQMAlB9i?T9oxxjt@V<2%<;P`bSH4*`&uVI!_%|KNG9KYci4>@9Yo z10s-lRa$A7uM z>LSc%*RWmR<`3l=Ki`BerY$tQKP8<)qjA4BUsQEgAYQP|v&@T5#w>EiRAhvDf*QiH z2|!Ah>MXj*6pNz_pF%HRRvBRUFO?q#MCg0wIOW~ho@Y^?TJYBZ0z=MOW|TH<#66#8 zx{PEel={*M=HiQ)(T&=+NsQ;MDtlzsI>R`Q}Msh zeVBpJyElUb!bCIBpL?(O7!b{Ob2DCnwpKDU4n?t7S4Tw6Ow4*ER|rQ&MtD`tm|_yn zbO}Y)U*iH)WCPdw39Cdy;#<7i6#Exn@NW+y60L5a3zj*-+#Fedm2=jnQ009l^{V3G z4KCONk$Qj6R|NY7^5o$!-zZsC8S`FY0Qh^7mr~#6n~U1lyZ~Ixrxq+f^HhJMfIv*q z&D8T66Vwm%ztA2+nfK7@I{mX@GRat-tZ}j6nKCzCbWt;n_6HW#-z?-97p&;K|M62l z`!0W@u@@U1@kdj#)B5Gj=qbN}-y~z>ES6OURI&e^i2zK=8}Z!Mw7Q3o>8bdhGj^&! zq!B1ncR@N>3Wp`py2cGEqN2?sfdER&9vHPh>Cnt3jLx>bG|=ROZTI`Hzv?u1?mfsI zpx^$7ZH#}V9$PnqcQ`cpWp+{)w^$nzmL+**1wlq&;YZ z!G_lVUq14emmE^1xM0kf_T}Z?ixZ+g%>O3Hzsm{i0G+&9y%qJ%Z%V>z2S{0ul?t#$ z$hM;DHgI)DyAtuMU#n#kR7`{N7_3%$;m5)L@$-br=mCuUMf~cXEdW>aCT;+Vv|1>% z*?T4Bku)fC;;)F#pB$&jkR8oF{)ubzY&9POSQh3_yi(MQ%??hxaM`^fsI&m{7)-VCGCNkUWWmcDoa@CU?& zh4P&JHR>4Zfsz5>1)H0jdk)uBajkRo43ks(jUh9OpDX)}EzE-|l^>n|6(;fV*<8wS z1ZuO#=aJxciM>am1Wyc-fj4AfIbsNaG#hmu1OP}p08FWPfHViQjR*`3H1qN*hE5P| zma)DUfqJ8_$kNA0QaDzHJ!pNcnAmw)NB`-LG|%d)glR3U7}^fCr=oQmLwp+%SZgx- zn2K^OF5%J+lxxdpfZ}_)6ep=XcsFi=NO@OV+uNZubCMWP!ZTN?AHH_U0wuJO)qN^a z#W8q<;)8x9BS@2U2Z&_f)L3X!a>2^R7RDvaPl4Vt(nJx$0@<-&%DIs8kwk~5eLP!H z*d>T9!@hs{b^&H3d7Y~ib-Q9{6Jn%b;DCo7`% z2c{IlRT^NdtO7t8Rwcb+n)?+b<9Dt5u0FPxnH*+5g`*8nDlSBg3{0D1V$1PpaoYwUynOjG!i8cH2QZ781DfnmAC)(-sr*-$BeREG!`SOI`q2o*S&Kq^3!A zwMxp&-rjIN?FCT&re*S&q9In3Y9=CAr2(|YJIowD`ksx?=?;MWkOIRCqNO@tGP(t0 zMJ5lF_WrrqmOe)>i5cH7di%CdFhdMUJY4=rYO9PN`gJ*I&e6os!Ir4CazJss%t7X3-p-Xcn}8d*(g)dhGj4kA$9d(^MUYuASI< zLJw9ZN)+ZgeQA6DXR7hf_X_BMG{GW7Z8MD!ysw#(mF208+4q4=t94czv>wL!ClWl6 zRwM2aHEVwEE-s}2vDT;Jnr(CHR{;2AiX=;f#}5+-p4H^aN6_^)n{wCQyu6{WPny4D zMl7^M?Bb*V);Y>h5Y9_wR*6)zn(dSA^3F{$Y-T~-# zDRP>QZwa~ohb=maI<=C08J&R~-e5NrHR1*EiKGK>zV!s4F3ufF*#8nSn1)fr0x+8L zYKa{l8!=pJp3FzT-l}5Z0uucd>Rx&Y(8cGSL!IG)*8dQe8}y7QQOCOuH(_4EL&rhB zos!oT+a}Yyi2BMI$#Nf(_%|QUnK_w}Fx@V-wJIseZv!89Z1)W23n1GUe5a*(sn0v! zU;K-_ReV@dJQy{`lD&Ga*TR$lNu95)?74_znH-~E7N`7~KsRzVZG$XEzvmz?dSwl`O@vlu5B ziU+Pd?FvH=l<+~07pG~yBQ32PVgMBUwRe3bRx^q7!&JfYPKiwibM1ld?z>xCTdwWO zT{`Ca*4D$ZVc*pK*)DsQZ#a)4q`6@*dZ)gxr4;`15<+NaG;QalsDjU*wZ_aiwM%(1 z@BALb(9`!1^~=8k0e-G|iG`+#3HE+}2x1GdlUR#0g z9i7)rFt4OGT!|x(QWZ_5*0GR1po+scD4Y7 zh(PXaj^?DN^NOE4cgQOii||DB4|L61%bM?o(-Xygs79uyE{0ZGuX>*K_yEIAyB)ax zDOJ=N2rOjcu|gR4>GphRfzBO?>o|Bx2{L8+XfS%Djz`>6pL!{9-U#D~I0XV&hu73( zUAKU?VjmUosSKMZWTb`JZN+;EuWQ4hLnYJGPMASU$`w;1qsjg$Qby~!f}oh?zc4dw z^x5IlX4Gk9o%44K`bsMUH|U(j8LYH6E6KynJtV5;TeFL0NL<#Stae}qB09I@m^(IN zZt89K6l`>g<~)>?8NVCzEm3LQp!zci{EeNeze_!i3rwZtS&~mBstV{S10XDD!3k>J zE#oKCQmHnJ`Gszi8{{GROod|xJ~rGFHlb5;kU^{RorS?N58(P+0xj6b=totx$N3+$ z$e#v4z?&BU9{3Grcq{b7lRY@7aB(97?+FkMR5-R7qsUgwp8Z9<%1e<@tGMXkYVz}5 zDb%Z1Qan~+X%#4P4071*DF6sAJf=57hOepZ=FEJ=MYD#@z3EJ=W7hWoM)cqWXeZPw zBDJb@?{TH=-ep|aBl@6OVFn;n-Jwi9X#0uRp>Dgvbb0SnlH@3MoZTQ99%%d)GvXIF zR~9!!pbUEpZgu&FzlZ=7y-NLk+t>-;P3ppmc**j`^VT)8Tk&2Vn)a^=lS;{WD4BL+ z1NUfmRll1O3JOnzZfZ7*?CPYVK2{L>2j#H%Q8g~i_ls#YWMhF>d9!|ZckjIA zB{kpo;Yel6YeWH)z`a;L@AoFwP!)U*rN&ts2XH3ufVU++G14`utMeB>$MsUg-LwTm zOR1`pp@mk4YGM|J>GGdd0~VfEPQ9Y{&C)0*Acw8(u!N8d35z5>2tel-S!1*|uwi4pjsvuvrFlt4)>_AandMBtbphhLtW-zak?Wai9X`@up z#a{F}aj_pqt`Oblho}g6sOV^`(?Cax#$oE|G_?doN^UlBzfIDRb^B+B@pIaTV(MN4iDYGP zZ;89^BCkc2%+{mFdbq+iFoh;}X$P2ms1iJG*B3oxj{9f}#or{bN^q5TbeP^(Lm_zb z&fH4bG~7Kn@e0dSNPM+a7qtwykvGiKtea5-2<@N;y8H|Qu5KP5l1WECG9Q)n;b*jy zntrf)&ATKh@55vHTF$P@fNtiOq>N0~gWX%l{yYZ?(-qH+qzukvd++be7#bT}JCTRS ztb*DQ`%7vm{C-OZHW~#py|#*#aJCYR=>6rMwp~iq9!q+(glyDYoM8BUc9c7J@NghG z@&F|QAF7Xf+sLMJ2_Q%LK62GsSiC*~U|*Kn)bD6MV6;i{(B|<$W5vyD)^i$Ic?DxI#-O zpdFA>P;emY)z4n^@40y1@;SXAZDKkhiq0K~a|d6fQK9R8`Z<&^$y5u>Y9_77Ha&ji z;(=g9>_~smd`okN^wrg#$B%XWb|)>aif=$Nvcqy0Ik^CK`)KN7b!xDD<4>c-d2$q* z69OR8;Km~WB-au?AFPn%0Se<*Tm9YQRCUZAl(4Spm>V!Xa}o2zzZ3J-s^fSU*C(|c zMcnWnwMVvUr-#|`Ysa3+CI6H@$nMT&S7RbXw5kzI0}QUIxqBy-VD8YUxmPo%!vJW6 z7PA>^hZUPWSlD8xvdCJo!tR2K*Fwi|AAs@_%{Uu;ilVmj+%kZ4Zln5ygt^bKnP@8r zs}BHEFJeZr{pvp*5=OrMd{}mE&xFf%f3sI=vWmx=waPMf%S%#qn4)4C9$uUoup@Xz zS-jDEaCX*(&uG8#Ws(E_#cen@P{Zq9f;^bZ(K-I%{$tN=YSY1_c(4$7R zoz1e$fYw1Tl$Ch1dvY-1MSkN@0FIYsb|Ei$i55WGwBHB7*2hWIYI4ML@#30d!yrUo zU*AQ%gpcU^_jRu%JJv92OZRP1DpFEdBb4BT@g8>cBM6H>3$R5!C}X1hDv7z|7Py_o+k%vRb9|)<-Dr-tF(os`TTEs}{ zB{2wY$6ahyq2V)97cYod*-9m;evr912@oCoH7m>bOx~q3#Ngy~Y&@BU-R@d=1J`fX zL|%2CZOh&M4QM^yU-G|sK1<%Z1GJahENMfBtC$Z-^ux|Z^& zQ(5Ah(~DU3CqUsa`udA5xVoW_7ReYp_mSD<^ZJ=Qzl4JbT8qqrqt9){dR*Qv*H?Zt zI;?-=#yZ3>uVEcvvZIr9Yv$sDa<^7&SIM)!L4GSYuZcy|T9^YMCHcm8v5{5CEqG(< zO)xmNiq1VLKKaS%H@a z9pYH|+?p@S^ei6A6bxT0;E!mt485U=0%C1Osin^gCHOQbb-KDyDL03^Bqyv;8DWD_ z^_%-V(*nd#o~xR?ZoAVsvKH;!ccz~%t0oV zRNuLlaH9BirK|d0iOGnN+WzI{gb~Py=Cpqy`5qgY39>qq6l#9aB;^xenj9EcHbVU=r+qmgwV zsKxepEx9<#c=_>_2JJdBKA=fY*-Jb^X@vu+L}kNyI&M%9JDaN|BruHj(4pmxYBalA z_BpAVomf7v5pObKDtDLS=O0_0IAWGpyHWY=+a}KkmEAX(7rURUGx}`z`MjY*YMp8B z$hUptovOQ+x_zoEDnSdQp;Rt`GJ zgl!(ZBaN!B@#Q^N>j$B)I&X#k=57A2b&+>L;DQ}$YgG2@a4fr^m*m6{c+wMkL zuHYseFl(?%(~I4R7_EoF2+!c~o5AUOzjYt;nFi(5K^Nq~6p{p#x=|qjK4jf)5w#$$yM-?&=Z5={5b>rBIQJ<6E3W5|*4 z&W`?8a*_yXA{G~Dhu)G5{BWq&T`rgvt_xv^MGP-Rlbed?_D*K^^nMUx<*| zDw=+kV}9OH|CQ=e-eL*i^M2lSt1ns0m5DARaYr_t85lCS z3}e}jPoB5Se!c2APhfA;$Lw?xj31mEmImC9h0D$jP?2~FBtfaSO1oaXYtQ*XuxBji z>;W2gT6iu|c%3|A^X%EPuTRKWZp8DX5##SbjT5K%%oVd7qwri}ckhOvI zKqmCqj2;%gq#4Wdeii>f_}~?gXyT()%xu(#`)DrgRfF%Mzea;?OD833?ucEIgkF!} zvsjjM($1P}vbZk_psup^MB3=nlEqsKVgz+C7;G>i{*|3suTX&vrkgm3(Yk@D+dW+p zoE>_~Eow8GA&mzU6*#naOUd3%@ym%q%H(g*c-bPsfpRyMzj91c>h)f053;#V1=YIx z=M6rU+-WvgB^1QgSIjvM+@h^x?jIMnf$k!*FspjX+g5vcJ&&oxH-W;DT91z6n1W!B z+}D*@m)tj1&V1%M#%P&$YN8fA^(9A_9?HtEGvJSWlJVuj2)FWLgnxwpLFL`OWY>~M z!{u|!*})xi;ndBARVn=PL?X599O>Ca0)&B0Z9zyueVJObHEhQ6vof+~3;X;i^$WY& z-h#lGDr9ktjaa{F)r6h^%e-0LBV+-H3!JBOMYAE^>9@^+S?93T$HrEe+r`ymP9~bP z)5>JoA%3i*O~iy}@J>R3LR#kSYyg3&YpI%2mSr4Bsl2W1AKdEiN94Z^19L_qcaHguqp{qPC%{lTBiO*6}+={%(2(D9kXBVv~YSZxt32G~!{CfrlT=Lyb z!^?!Dqf_qE&{!YXFE0vaYh=6{scvr{{XFgBy&7FwysNOJ8GQfU2Eex-u@B7-_T_WK zb_F^*CXWR0x5$A;Uca`F%5#^tia5duS|*rXGICtenx-|&9&~zG<>CDeeJSLo-@{qY zU5n?Z&xj0K+`_>N3zJ>!#~=mE5@t5o6K;v@Ol6OXOzS?@U2=TmjB?I#ovjVF#x-u5 zCx3ywitN=^i8d@8fY@AjcXQ7i#Q!|WU-Iyg>O7pNS)dxA@%U1jVjCrT@I{t(Ta|N8 zzZMt^Rw$>L%(Nj_GKa5q=ZAwvhM@qLEG@vbmZOaChgmf(p5G7MJ5#-RJ3`5N&u6p2 zuYQl(a(^s?YE@T@z**!>$<|;z2ALqAJGYpRwpw`C&Ukg4+Z@-MeFL+Z-q8nuUxKRT zb~`B3d?km_;F%L;@x9No=Std3lPazR1}l#BLr$=qDy^gO|C(GC#H;+WJ)>JZUrU?HbZ`Eq+Rjp$&H9E! z`=M3|x!oFKc@<`t#Ij9@W3E(Yp1UyxI1xeD2)oK$s(Wkx&IWACll4anuehh&(ie!Z zzvh2^#3~J_vgOvtBUPX9BS*})i0J!ad2na z!-a|F$3fUZDE7iiR6&;jT*CUp`EL%v=B{Q{vxmfoRv7j0J4^NAp!MUlJ6Pgdz#Nlip`R<#TR-<<% zaQL(IdEV}cqGC8(Xy&k|=;_mR^c@wiwhwc4VE5Nh>kLeRdN*za(vpWg@A398#=0Mx zri%tojLVYGBxJe%g)G(QaerxPsRVsd@RU-jqtuElNFsID>GA75GsA7^`Vot|!HodH z#G~)RW2mR3r@HHra^7m5s<8}&7+kfke3-Ul-B9n~SxnxtP&$47v>|o7?cXsYwJQeeG7;MfM;5b}ocz z7E+gLokj|>)<4SHC!&kTv7#`0O%~rh$-sH;XIB=JTp0sQ4%8|Q#?0iL(WDUr_-)^R zRCzO>ZXUWa=S)~Opw+8z%2J5fyW;BN!Xd%J3r|ipxu5NVXp=BQ8>M7KrDOJ0ZKn68 zZQ^BptR!mY%A=whI&251?QyJUMg@%Hj`Q6aC1KPg4U20Bplq1|_-?-~Ipp<JAGVVGUeac<^m+k?>k(+ zP~+ERgSYDsKnZsbaxk6&^2g7adQV;xGCEuPR;a=neodSO2ra9w>8-CA;CdVzD^jNC zl+3wR6%-U480)%g2F2xUwu!nK2Zz`FibAVGNoFQN*BJKR$@O)vv)Z{9c;glcSB;Fy z*MMvG=y_8Pzdk>%tJsWQnf5^|=nA#mJm&ghqa5PwFQj>Ytj5c~Q4b1ASx^ek4BKgO zmI1h7Jx7(WVN!)^b;_VwHW_Z=q@*b3x8?mMU%#@1PS0si&PD85Sckc$+kDwc(szD1 zED*7BylP^D&v7XihVU$IU#(#L3IrA>c?a10w%3W`yY0G(CKlyed&r9!2lDgVB%PVyaZm^)GWXU}#nbC%4NY6Bm5yBaIu!$0`khI)J1KZsm;jM+7k|J0(R# zGmcHJFE%Cp;#YWWSyb#JUAbH)|AW)H8qucpWVG8;h=I&YThEiP*O3+={^^s?Pfi0`BiLl|VB`P}U#U z<>WzR*6qWz?^#AbMfWD&=M#Qw1f1Pd`8h#$1G;WcdGb}(H>01WAKhbucld!v%--d;-im; z?&8)-_pRqcAGOB~;yB|3PtIid$KpeJ7rnRx5qYYv;Dl+TXlD3zZRPfE( zLmDizBc1%tKO2FB{OI9@?vub>L*%GmkiuN(8#YNV?4Xdkwu|nm>mS}+6-;~{p|V=D zTT|E^*jdZo+Q>f4A8_Anx~!yk?dp`cB&O@Q=el(Xlf13Ef8Gts3@eg2Gq1^}SWh>E zeBKbvfEKkT#+sB!J};@;lXnp`KY-iHEWXGiVSRF#>rJ$=G*^G+vrwiAwqA}|9TUjs!b3HOnXf$uMi1_TQHlfVFoTzCDPjq6Oc>=pn=78Tq{N>+ ze|`dGpN2mN{$jAyfN*z&TRo!2+Y`KVhu)PiDiY-|_PgKa@{L|hYKn#+Y zXSo$93S%n(kB-*#j*^M>#j%aIx1c7UFE4aOpI&0h^_(j;F3Ov;!4ab~X^U+0 z!R@?Hjw#wP4}LshqAkD`Y|rx3Ee;5U>8tMIOA-OPv$TcVVQD}uFI+!C zd0PMFQF~q*&NENa(@#2Q`F_BMH>+%*Fk2fC|NqC?cLp@IZCeWhQbbe~4jq&tBB1mZ zKt++R^bU&D0HFs6RTLBy1f=&ay|;ua3er2FB|+&eNC^Q#`L_4Id-UFW^gHkU+mN>Q zT5HcW=Nw~>Nm|)&iQKd}Vg?k~QJVz?*LnYt`OE^@Xz4L9t1Db9?2xO&ho(C+%`yh$$5Y46(1x=C#($w;+kgWm;=xud%~ z&PuM+QQx%RTUklHT->DJNUd?O!DgiD;w5B&k9i?g-SfBbxj7NDtx*G0Lhk6R527Fn z`3MbyDdeEIoq?gxz~WJ++^PA+MJ9~rc3Z>=gAv>WCHRY|*}J4==@x7GRRuOD&FA-WfTA$m%qipX?9P7c|{N5v9+z+=u zekRL5U;XzY zc^aa}VER-k#x4`1SbUFls$a#LgdIV*R@&vG6NBbW{e@mL_R=P?w$!s_cvBcjF%)R3 z^F8Bgp0|3KlxNIT^__|FFSFzw9+2v`Qgs@S(Ksh#o+-?@>-VWkXA1y_ruK(TeNzHp z`n*;Oi7gqq-Uk3qw3>R#1qt$xbGCqPAtuLSjl!J_c7$g`FBhtwyVjpVCz1XI85*jr zqyafMxgsQGQkpp<0vhD>scRgkE|cztZ74c4r$__-k8ETcjr8YYAh1;rsTLeI10O@L zI?2wG+utCfe&&C)9#PTeVKiZ~kkIhty=vNUnqc$(ZEh?ggk^MXreyYhcSl;Uht(Mr zMDmHNxMztlu=VrOEu}0zTz7SU(d6r+cZb0;+_K$>t*UOqRMJ4xSktQV1;4;&Rg%}I zh@i)e4~pui^G*ANHIq!GtoOGr`-L<=?bPJGcI_LiQp@go7I@wn5+>%syV}P*avqlG zC9JD!xFC@EcpK_uV zJ`53Gu--R6f^%5~F!G=^+v`Yb7DIN|#bbd=D_`DWP)3SL`x|F`*6qEla2eI(?L!rh z$xm^nTm+3t&(8$y#yO}iHC9y_H=TS@ z^jcY7oMwk3hH=dC-ix5zCr2AtT}CFRIiLmHd^iB}Ao@vQGTuc{lvgFQ|5t{ZD@T|0 zOd*97*h+lrZUyeZq#+oGiQlY2yvmA@nr5;3*X{%mrA3M&K=>lfM`{>Ub_BF5W^uFy zns4s9oyHn=?&kq6QS8-_+A7NJ^DoJX_;tOo6M3BgYGo6lm&WG(Y%}8w+YD>7sV{is z+|(;Szfq5=5yX67zSi`9;At9}JsPG&HrrGS*m^wz=;p?@e#Nj{YU*iC=-2^ep_P@? zC*jkz>_QHc;8t3YmIubSp>ZfteW?G1V51Bwcp4N|7X*+e?DG8k+{OD&5wBnJJX~Jv zy^IS^yi(g_oI!?ctDawY8bui`?G_7Kp*hn^t&F zq!$o?P`OZldXr*P6LP${N&y6@3V!=JIRBj|sy9vAzD`zDRH%u%pA2{a9MMDjnk-1_ z*C(^t4M62ZtKJ2L>^OfMSqp3tw@X#GN@+M~+^i4L7%uaw$#2LSolDWx)8nC{yHPee z5Ur|j%GVGV6Q`u){HpS0Ba(8tJhxwcc(WyUN=Z#6#-@_3IJcym#1yW8ueJGdWj5Nj zZU5kop0@s_OItM49#&RX4_ko#884z@QY`uU#6?DoRF2Xa#-oraBop&1$SCISk3PR?uJ`XlbgE_1&6pg5`FlMMzGBua=XsmZm&DuA6BPwgl*? z9{1~iKm<#H#2ZZ~88B_{p`|4jqh_JEB{yvbPPtlUf7z;}r~xNER*&MGapc`QO*9z& zGR4?x&&$ZqiX8&ok=>S4Unh$q$-Zb}O3M@GL%%!R1%>`+(=@O=) z#VNWZ$O7f6_3GwqM^}{|rfm3oU{JqMpmJ33Y4x=~h|n+%IT+BKavt&6&30W}vHl(y zfG(J%Euwcngq40q;boUnK7MZllU`o_2n+kBRKN2KP$Az8UL9e|l{&Z(qFzyn~-Py zQ826f@MKs!1=e{Xexr6Llv0Gm@S@GJ(e#jJ&*~uY0a*lJIn+`T$M_2g3RQY~x{}Kwj&%tgotN@_ct&@q)UBhK9I~)3g3`7djxr zvk7chH|mKH%1PwlGljeP%G|!@BpP_P>ZU^YT z8uWgZAsX=JuO7@c*KXAdpY#lC#GY1*_dhuu;l%B*MF1>)msW(_wTQ!6Uai)n%Jk#c zXy-GM$8~buKyIG2*Mj&@lB#_FMbG(|g@V2iRu}n)H*0dTKu#w|z{aUs7M@FXRgc@N zTX^z}zqnh5#JeIO*s342cvf<;L1pc+UCg|78tk^Z)R#Z-WgTk`S;^UV^~KpucB6Js78Z%ky#~=4oUP724mRI!y=dUvx6~ z?vIKutk@P?mp!qtm|x)&i~)MEsEC87oEKKiXm_X8?w`dNhpKH3K$-}xzJ04oBMuWK zmHgNX<8O(>=mcZFqmQsPv6@j-!^szGA;(1)1-=~c@P@l%ickFw13=FmT6(E?TDIlz zXiO%1SXsGy?nRs_^uF{_Q|r@FzL(~D z6XK&xt$$K&*)XAv3>FK7D5*G4k0qNSRjv(Dev*3WszJvZO*^~9v#c`ubo{2wmq=*b zuNmevm^J%Z>3*}k?TuUEDqlEztx?9o{QdNVZg{=1MrpDse=vaX(^`Ih%OM0w-FW@L z8s&sPuyO#v#;B;TY}&|BsUWg*4QoV=3HGK&o8IzSg*z>$@yxEib8 z#D|slFiUi2dEa_9_g9Xt-W9lXv%IuE88XvJOcZwWSEY4s41vcB(!CSH7>J&KRidZL zsy$E;<2>b!?s23g$Eq^k7f0`IuV+ zw4KSko!2%^xz1R_CXo*L>-L$%X51_lO?`s6j{ z$_L*pF4}=|e^rnSGGK2rt}x)M2B(|LpZM|n(X%X>m+IS%4GzeIF|%YPh4-|B9mEvc z!*7jlsa~Mn$SFD(5IJw%CbtNr7CU1Ool&7D8X^2W)D)BFzV5%k6F4fCJB zd{1Y3C*0^5zm@r3(80$+&pJ$qsc)lVs?d<%Td; zZC#zN4FFA21Zq*v3q3EPvX$Gh{|N9y4-Uwt*p41vw!B_dnZHa`B8uQx=R8>LrV zukZkX3ipY)?u)!Hfv8VmRGWLLGIxzYqe2`U87R4uD*xsppoj-#l)k?n#v20!vok&R`ORSGY%y7j_!!QS{@C|>0MHs3o zT>5kqR}cOPmaa!8^8U7>R*++n5@V0dQEBUIaZxelM)a63BoA{mRzh&L?OAeg54kYq z(X{dewpQtwykdP5;AMEo7{7p6f9W&rn-KVk!A9;D9N-shBa%kC&|_pPUOQhlprb5p zVP=0i@BzJ3Q^x?TH@(NCY%=OB+t5_%rJ{Yl$=u7=Zrq59;nV9}5q*)VN4e?{>b25| zOuS$R9(MOXaxbA+ANxFW`?O_C%kf1v?jH1{SlAd{_fSr^{jL&K^toFxQ&X@jo?ybu zcl&*-sCs%cdft%f;&83PY??I;^3vztsOnES6`q|!24zl4<8SxdB_xW`rZ+tUc2=VW z0kT?!%P6Bkg&RPesd-|t)})A?P0dHTuObmhs|MuP*?({@7onWRj4pRo*U-cVR#%## zsr75i1z2D9lo1&9n~n~iaU+;mzMP$op3aoYg0{AHJmviI0-e-|nW-*o)v}ZIA1lwi zuRPbikDNLXSsXW<3J#u-rn8}$c6kT7B_FhtJ1+B!WXKic^lEcN+werU z1}Qyuz@(GdS0ce#^$T5;-m9-;Q(_ouuKQTqr#Y|>=#T*CFSqxqaxol!-!EZ1snI>h zZ!iwaBj3_U09i2=btEJtMgJV5mUKo8QtoPeE6 zffmptc6!iJd;@+Mzgtrt0Ump!CB7>#!S>gm07|`h$RD;g(w>KX<^DQ5n*&Lc70Na* zn_Jk88hLl=Raltl<#yQDK@aq;drI$iR;Tn1{y;3n$LoqSGcoZ2E#9Nj(ll_py4CtW zqWgclf=9RP@!#)a=}5jdb(Z-?{;OB0{MDU*iXi-KZ2l*CWll@^u+^9LD>TFeJOJX6 zHu`wTRzj`XeO8?BPM)Gtsc9qUR9(!w*az-9)gvP#5ANO#QczS>x%1>1CpV|^ojcDs zxwsN-i_d(ydMT>yuO~gwQ6QZI`kmPNZv*}5Pn$x(udGo9(6#kT12)=Kpm2^2m$qGw5no8t?y` zWQ;=5cLc+CNz&;Tsfho)gFxJcmv7#b7b3?-OZ%<#>3`fbz(=ndd6#Y*DHIq0%a$2p z=J}iJA)iOd`4LDWi&m3NOJ9zC^TQc?(A>0tp%8%CpRjqKWB&0|zr8Z|CAmoZb!}xn zMs&53VeBUzY4!){kTmq|;VYKJMED0@*^=si_on-3Uxr4#%l1SxW`3pQ(j`%^@;F32Z| zj~1G%-gzpislSCEkQr1pJkX6#hvnxlnCc9EGMI^piHn=Ny)R7|l7n%14VZ;Rs-^9I0`uA-sO%oVOujS@Ek!;3z={~h$BRuj zITHEOFn-t1t;L&4g6L{vM0mJZ;1su#`serA4){P!LUE~UH17KG=;TGXykDLE+z4J=Yj){v}?ah#RD)>#` zE6#<^vBTG4?AOj+4pgVR>1=3#SD;<=5}%(`Su@=c?IkqKik3ugP8feA-)n4NrijKW zMK|H!c@tY|R|QY?5|oB_e6uUnv)L~=MZ8l?oc*-`*}q$arAvVe0gs}or=@szuhBY2 z05fYu3m;{V+6S0Wq0*xeY0}g;3h4o42dbYnwrgrai)B+p)~r*Fshe!otl-oWQc6?g z+F##ZSaJ(=XTV>ht*CA_a((uS41*I@3#wIH=;CT>(1 zO(Y!I{4(p-nTAectZOX)ggLs6u!}LDvihlZ=>KC=B`!~hx-nTi^G|$S%ONj}wz&=m zf7LBi0-qWPmj@h(b-J=Z!)=)gfJ8j?d-%M3^93?N(=t1P~o@_0bYhk)vmyHarL$D_*!w+sIfY2^w_O3 zRb2PsJf5HV+ji~)l>`UW?AwDv)uaIoTzRNT+KlApAzeIhY&l#UXh|~|2qsc%sTtIE zjCdu)6C<+Riy*w@IgwApB(2Z8|_i zla9m(Sfmz;Nd1_%k1$Z`N{TYiTKX1c;yTyo3pC|_p(onUQB`3ZR0=EU3h6slxmd01|!C1 zn8g1oMfaaG`VWIV@QIY1%wzM+OYA=nsR5!u*2_+8=vx0XvhsPlPTfP;SphPViG3}8Kj<;eeCE6G0a8{i#^rZ^MD3l z{^^H*KdgU$)fgD#6_9Kzyp-V+&cIQI@qnbMaJc}T`p7M7OxPPC)^ES=$aV0Y)A<+)R*qj_o zO)Vonl~{pjz%^3>@(P5AccQ;poAh2{R8Eve63t7}U%CkJ7ytNyXNI4AXMl_fKve{i zZ58INSMo(4|ErJnFK+t3=ILMW1CW!YEh6ZA_?tH|&su|k_|KpKZ1)u1Kw9DRNtu_I zHwK`~*xK8#8AMPjRt}Qdt=i>eWIWE=fcir9F%Ja+Ri0G@!`KhV?>{Ex*MFv~kbm@e zWm=U%d+XLMAt!l%UPGfBg?h!YU%y_2f!hjh3GKUgs-ZYXG7d&EvvhlWya`&=uZ&ClnJ zib?p=XYude$*%|Y)B6Ik*9L&qJm=`4o12|*vy?1J^j%Ra<^b+(n;wd|d+8CL(Xli? z-vJk|qSDR9!C~qGn}11$X;dpEo&oT8Xh9+AG|4peED1*7MYehF;t2JA04a1~Qo@DllCAF=p0nXm|_#9R-=vyK3lCon7 zMLjH51@K9?wv-XZ1q@gLwZara zRP)gz+Yn*lp(Em1aF}ll20*_!xg-tjz~FnQw?r43%F72Gukzk{6r~l#*>#9C9LBks z!Tn9-`gS-3WYsmbG$&cgfbMW_zeZ^yx<}qUReJEi3CcFI0hh`bi&-ly1g~v&eEJl+ zE8Y40#0ZR|#%Y?GasX_uOu~q~ua9vu?zJ$UUo`Jo6WkW(!=i_O{@fGR<4sKbi(KSy zcb6hSnE<$}5%e#`Z@U0Z0f)<~nViI1A=W@)Rl&#j6QANv5`=Fnl==x+0=7OG<-Y9$ zWjq*bL6G%sZ@H+NgN$boNKUJwq_p&uec=zs|WZ?vCy^?HRrMrtuRP^3X zcEH0`@J&D5${pGT2)UtIud+&awuWCS#jZ5kFYMO;qN~vV7`*d=#Df<+dzf9GQ`*R* zY}fgjOGf)soDe02mj|-4k_schFMZ~_Ml&<84~svO%!*#ZikRr#UG5W0{^oNpNATgs zjoK!>j*gCF9ZJ^}zou2|5VXQ=!&;z|=-vn<7aiAKRaLj;m<%TxZ5*5jR#wWNe7X+Q z_!Tpzy<1{+wXldT;sw}d0za|Me!Dh5Js4N?0w}SOgmJ~`Nbsmfo~WKQG`GqJGcaI7 z|3FPGwy5W<@ETPukbF^o^r+lM$F;YA)ydRRu=!0)Ok9%Pa?=bvxXl%opuFMS8-sRl z(t2!icSq?JBQfM$B*CF5Zd)?oaQ~Y6^0R~C$t1(tjC+3U9;Q?edDU>UWdt-JB>kgfruehgE zZFRvV)2wXtf{osmN#AN9V8-#1!ctf9;+US4Z*Xia)U?E`&V*i7MJ)!X&_IOix(Esf zZui+sP8g&*Asi*UNG69>*+FQOnn|Poyca}g*VxrZDR&Ewufvf9nsUG2r~;l*>j5-) z31yqWundR^-KZ zz|&XNZ;iG~4-E|u-z}kIqUB@Y{NdILyen;&9KKMMG7U9N~Azr-3O7Nx6&8ee9R#1xmJ^1W?w- zA|?A9^ifX6|NDVoF-ceCQdzuVba6StT7m5Z5Wq$$uTVY?%{Wv2ec5|HlP97lp94km zufQBH*Y&7Tw7Vs@VrElvzw82IcD9DQvRQVufJyN!Wp%>MSMkoyU(&v!&Aluvgmu*% zTw7$tYH+gP<|>R~v1!oi0%Al*HXxl6+yMBJ4DZyOo8OGs!2O zabgt$;Gevr!#lCjDZHJXo$C|S-9H3B|1wPbXRKyPx*({}Y38$Ee8adw0YIkg{Dn6v zQgSTF-CP4z1RINz*oaX7bOPl$#kkuq(TB%mKbPoypc19vsv#`E&OV?;A|yPNQ?0zp z0@8)(Y(JcO4|xyeQB+h!v^5=%Ol&qZB#VWtH3oV?EtqWCrE=>}7#M5;ru=v=XjQJ_ zm|uBFQ)|5#kVDjU1wxd_l@&YZif=FOecGK1;M5vS`8(0PJd`f}_+V=5P-Pgg%`pJ| z)4B$}x$zJ)z>bTd)_i1e6+9NJvXShz9Fqc%gbm_66k8fsLEJmJ23|cYlZ4^Ezni?>&Qx3J!A$*OxnE(ELh3e%P9c~4U z7Sz6U+pjb`f67tH<7wl)@j+W{5zTJR;lmar@bZ?}wgZn@^sqY#Jg!BA@c(n zq0L=Ut)QUl3M>l)&_NrE8jK56t9OCgLTsgw@N}oBsCUob%2UDfS_*Srq=BxZ`{RS) z@6#W+OJP6x)QE7COMmQk6dZWjYnxd)zJ*Iju7>`x|j z_9d?xtXGFCq%EOx{xjVJ4bj_p88f2C#dD@Qv)#G(GnMT*Sw%Wt%PW$ItTnpKUsux5 zh$f-!8Y_bVMalqT2T$t${6L%oy5V*8QB>TNif)my1Lh%EzoDW)SyMBLON{%z-Rg=x zsT*~(v|4R*z7b&IMiQEA&znS)*VO0^4Qp}<2&k{9nKw>qTa~_l?}A83OnegTYl*Sw zasJfNF)`5W7yP|y8-!NSVlYLHhHmJzx7Y$$dmsDHWPx9r3O6PqYP|2}Xe}zY+3iwb z>b3M2%s~FD>YfZv2ia(D?Hg`BVTr2 zUMN|sxcjjGS>M(}orQR&^>X@Reu@eH>dprm_@ua$6kByNeGAO=`=rE}2W3f#7o6}} z79_trr2l!Kq$iOtK~}@)_}94`bCSq+WQZV3Vi$w_K^qt5U&0duwwYbAzDL7_+zO@x zHH9FtoxDY=Y)+oZ0GOJCuR`z??!szM^2205= zyle@rxv=%wCEny7`;4TO>A~7+n*UN`pPw;LM0NPy#0rDefpSBI8+rXA$lS1q!dVJiRFLTu+ zQ}v|`ut%Tt@Edn;q|m#>>Uy&cG(%o`J$jr=5KN4ZA762qEKOds@9f*saRwr!n<0#r z5k>^mkTc+ino3SAup#f~8|fX%wlhPFjg23&qnoW?{~eTTpqjMmd~z_MtE&s)p}5RK z4APems(G{!(emLnXz#702#Huhz_wvtzi8eBZG-AdAHklJ<2JD3;Uyvg?eJA?iH)g~(J*Ojk*N0~4FK$&+GhzO~}4fxkp_gg?itj^&-A;G`d zlt5iW8}TE?n?u=;=H_2Z*|&%O7zN9v0etd8W1cU~WUHE6$LJG;Mc%S7F_Q|rtZW~) zs~)3Iu$24p_TO9qS?6nC(4W}Y;Xwa^f4*<$6cOx+m_3#0!dlz9Q#f5*+M?OSxcB(hoUj> z=@_&9fy#mGk`i@C_-5i8IK<6h%El|j{bWR0~BY5HLNGgLs;unJOGWH z{$y(Ly-_5lYuVbA-K^)>u5JA}|Ig|e@^SQk$k+rVJ9m{k%9;7hyC;Yen4k?gfkC?% z#rBA)PJztTB{4@Q3A`w6H!U+)XKi$S~%z}Lq{MLj9K`3EiS z@B(X-(7OBnmyWcxEdo~fwg)4qpm()`ofz~8pqgm-XiIYc+5n4{%UkNithcsP)~@#5 zUoT5RSt}{!H*UO^Gfmx1>`BB~epa(Rl@9ew-4WwBg~A6A9o-eE&F2vl741~3o#q9E z#B0(N55K(ifacfLebk~O+nhQ9>M{got+v3H%zfumHC2^$riFLD1it3q+W!+^5 zZEnuS|IaF?FH$o5edFxhNLgf^$vC5C=i1`C^tKfX2g;{qfXBF20|G_Z=JRUmE3}|U zAE&EO-Y{#rBO)=Cy6f*RtE?`!t^g#eZ2Ij`PbOjtbrGyDUfd&@MtsT|14%LL8LOzM z#6)Y@%T5$jXAL}~hBO|fn%Dz1#TT3))UWqJroaqE_`j5t|Md)=UwR)9JcaSX2Zl2nk$Wqg)R_1yXYu{YlDT7Z%$0*eNl>l3>IimbRey*)K+;P}5ob-0~y^0`Q` z=^d~YjYP6l091CDN@nNVtdL`mx{%O}X#SDW6KawxTEOU^%3_%TN$X$k>nbht2d(C> zA|fimq9P()Lzdk+6%|9MEJ55m3Y&xkWH-7fFk&yyi zTsfH;kYf9$TZveeBrNQ1)fu+Eq^Fiv@FYOasZg&p5|HcZ0(8IyzH0@fK=B}&2SBEQ z+3RBlw&JIX-S6t?7vk&sQ#qhj-Qz42bs_H_KjEZ!YHiu|@`BNG(3~8r?{n40ZB{SK z$yE=A#>|O)9yUQz(x49|ZD+p=&Xw5=UaZF-hs;HV^-(vUcLgMLvw@pZkR(*_fd4?KXy_nuVBUhn?`L?pcjP6;`3!P={KzMx!b=Ksjyv z50l4iKQF8~z!bXpbSA*B z+_cuLsu}O|*$9f5%YJ5YNPkvX*T@K5;zP$~hbmK*D*quP0DCm4L+Ic0y*7Y z|F&Rf$!rHuLkK;aI-#UxXJ^OR+Cb)UfB4zC@2JX=u_GX7j(YWKv$;UodMDCBAsD#% z&z{MW%D;Yq#0pyOEu3*ay5+r4G@+?o<&m`}EiK)Bs4rpI2O?CxsgT=H-|2uyYe?ya zswmH4PP_*DytneL=MoDAw*?l?>FMfpzGm2nS7|yC01CIG0r{5B?sYDU4(wC^9sA{> zQ6LBXT{~nRdD0tW=C`i{RPSeNr1?w$g}Ig(UwoA3EZWeh&Z*pofTG#LiDQ%i0FUBe zCk7C_Q{GK13jyec)iv;x(pA4B9CT~Azj^$a=H~58kO!NfbogY`C=Ouz%vbhXbuKP! zbVPA=uhHZkRnZtlyz|{n9azahxF1Ex9%wfajuj0Wp5{vi3w4V689_ufcTv{QmM||` zboKQ)HIB9=rS}18H)X#K^zKI9?p?MJj=Pj=782?HuI$SA?an;m`R)GZGD1Eer%f1l zjWDsC`}`#kVg4h+GpD6eorFANdN~?^rad`~c+Fa!0)S(asVpAfIP39&9b(Rc6Ch#} zBX&t%rQNiu((iU;Jlu|S#i_WeNYxaOul8DOq_J#$c2Cp5fY*@AFN{ApfwmR;7APw% zQp=dC{`6@p?WBRTviWe*M>fg2HjA)kt*$%)`@mWw2MD8$De>1B(subGwNw0;0ZOv) zHpJ224DRB85)8MU_NK$$Z@EE++_tGM#uR?zQf&H7C~(ny}Sl8QHiENU6db z9FCi$`$4D(Ec8PvqB|pmnH`WJTgraB9xlC6jiI`iv{C7Z*!S)f>YoB?O4LlfE#W=l zde=vCNm;%ZDuv6g(A1RO{Y*`&diW1v$D`(+{ZSvxymW>tq3RP|(v&}q8%%^`@;bnD zEY|$q)9L4j=-)gfhwo)-v8$zxnZ4ckccdB;SV6~@qfw;Q=lM93^V*v$FX+u8VH>dV zqgFI*4IUm$#Ok|e%5XEi85+xC+UWhp*m)i&HqIikZMl7Q?lcXEyZ?BbZ9#FQs$~LO zXZpmn_QH6oaO>eCY1QbYTw^fdyaa{;nLcorMou6?cK4ldC-kI#+yZ&NjbGf1$B;u< zn@>O>a=1^z3@8qt5jP4t>wQ*hqoJR*`S=uLfiDhM>oTG zr;{qq48B>aKC^!2Ck9e0F=9h%EJdQ9WT(n|O%LNEINP!QG!Ft+f1k|}Aiqj{bbxoK zH*EB-mR@7o^I4#G!S1*6xP#~M{nmXowI@v?y*?iBvQJ&32NRld7QuFmZ+!uAq;&_N zxT)*o(eAnG_>>v|evn+94&%J}w)AMQztx*?9Fq2QdOW4gF^GZOEjEDePTg)|_k4uE z?4aLCmOl-oejVacx!-5$o0R&}zx7^5v+FRe!cMN<9}QpN&0X2A2+yZc7q#qfH=h}- z@m9;2cE#M?mA<_30TAn=YxK3DJPQb%bGR&XE!Oiydc_TYDJZb3KbT}%uL#^umQ@qS zcr7al=B0UOX6NLP3A9TP-zFZstrh=oJLSK&&;SP!_3p{Mh9Z2`&*6gzdbjlq8z69s znx}U}mf_H_^~Zb`%M}M%i_6v~*BD9gV#Uv)9|t=Ci5e){R#9?p=15IP+H6nW-?L$V zOuDgfpW6RmLREZP*1j?$Gv+f6ZOe#m>OXuxp-G6NcqRSCgL)P$!7eE|VRA2MB`?i6 za4Bczbdqio&`_gr+6i8gx4O|ZCE)npG-7+rRp26Z{24K7abwTT80>+RS%mLbKiED? z2Unb#MG#fss`PBFM&lH9E%;u=mt1%{I=NuY&VOw)4;URzzayMsowe}zX0hD$;UDe* zJXjv6Ndr#Yx|D>?U4n<_Bp3o8-np(NjV&vd2Fj|*pVM74ojUXqxtg`_HGkuKA=itu zwX3hX(ET9?4A|stfpR@|*D)Mg1BQE(?nGz_JX*IFJbJz0pl2ri>G?wQH+7c~T&PJ$ zij(2PI+NOrwEg7V%LQycOKg4D@Z|On17-Icdns5K5rl#08-P4>xHLMF2vjb2bGihh zXAdsvT0BCOOf@aQljip6OEp^0~h;3f_Shoc+!-ICC`pBT}89eDUkN=cijsOSQ$ zi0T=jD%{m^5c@AJ0BT=ZSduQZc{6vaG5U}D>_q^TzisH|?^63x*B|Pea^w5r1uFdr zX_pedj2U{^C9XA0EV%T2Jk8Z{7QFh}p{fQ$eanBmtarM%M8Et4%h<{)673Ww?RQ|y zGfAn>z_9F*NcJIb+9#v|kQ}SIGX}Kuvk2PgqZGFGT_&47@f`W$vcQn{KvOd_#l*}^ z5UJ7h>G0t}NwIQXE6x|6FjKUG278+Nn~z*y&+6ftOxYdmNb3Z;%-AYchaQ%994nF0 zFfR4%B9P}B#UNZai(l_Y=LeU>d~rXX#`wkMrTVF>%P#9fQSI&br#gW0=t1@2hbNcg z%$9V$OA8C*c+@Q2iiL8IMw9~#JJIpI&ifRFtMO8oJSpA=%$r-I%sy08+K)fr3{4 z^Xh9;;uw}OBI;-}xqV%zVY8p_+)!A5^m+|yGS~tqJS>j!gA_<=l&8_Sx32bDf5}Vr zeDK5~X*P7bSBH*UqrMjvPWG6`44MP`THZGh(BOB@t)$7lRFVU>_6O!N!}R6e78Cp- z>ga6VaKG%Tw(EBZqhDp}jhBo#&>+)9P^Dg3Vn(5cNgZy16%brg`@LdQQ6e+e*WM zBS1aVJ`JH~>KwTSNG~|Xcz`nI;HwaiG$ZJ=S1IqivZRlnMCBsfEi`2IUlW)|H)nfC zsqtx55l2n;niU7{km2RNy|<||NlInkZsI+afmt0mZ=(dn@chd+f2iL5#47opphSxE zTP@NwQoQM?Kn>914h)`g_cH0XO)00gHe%XF6K0!_zim`i0X&L&mBN4%Oj<-#w7Nt) z^~93U=H{l$mwju=ux>$DKlc##nP?4JXorT(<{#qICA6ZPPOm5~*}Omc8rBzC+(v?M zpXd}f{%$O75$jTYyNV&zwgc%oyU1?AEksYXskc$v99qRe?x@s1EO;y>H_&(Sj7c%v zubSdb9usZeGEFv5!Ym^o1SoBb2Gpp(c9%+3_Rj$80^A{$Ik>E$FDkg zciQJ&If_^~GwHN`GJ&9Jkq9jeoYff0#|uov8n=jvUJ6p%Xbd?OICoWksqqD!VZeFi z0FpaPB;@($iR00*jf`3D?kIkvPb-Z++Y1eaV5!T62Kcl&A4FwkC88N|7m9#jY~G&m zi=XsSJ0d*>2hrVDjC<(@Bq^EVr+ZRGhZ|c8>8<^pcOqS;%jKYn-+pwyzIl#h!G8ZL zRIq6udj@LAgFZ?Z*M|mEY;99l;J}~H5|e)x?r*X=J;Fjs9ggFd%8Vl`vKz$cLXY+% z{I0^5A>7n;zIz$4X?rZAHqh^*f6v3>nU!8QT@p;LHc|9o*T{c^e!Aoh;PsB`9Z#BQ z5b}!(JQm&WtnOGr@@&irw-njt$!fvAy1Kc>u-fPIkCZSyKp0r(8F_*J-{N6GOz zE>nDyrsn&pinZ229vx9P3KsmeMh

;Oysp%Wq47RZM%+5e$tBa6WBz6nds zVsv5#dHm~^m};g}9Y0ix3g*`dgX;7SSfxxN>!BM{u}dAxHY>oEJ0!w9ykfq&(izcx!D|@Jesf4%Yn&RXkGCN!zF|v651IkhgAVpWqu$kyWt8#RCYB-5 zx|t1bh|xH-fjGaJJhS`8@>5d8qG;+0`jW!Dw}Y=q?2nAB3!%5nkQrgV2R&CV^v#Am zj(lSxDy7nx!Ee@1wmUh(F6Kl$P3}?FX+RlPb;a5rKNwP;!Q&FDu_JE@XI}7EH4Tjn_80g#WyiWQeK!! z2SBV^m4)+rEz2K-gdkD2H(Hpm6YAfil*jnK-l&BE&q!2{45I@HhZVFjA3INGY7!`D zCJ~L0ihv;GS$yZzw&JZTYT#^3Nb-l!Aw0OuSS7W_ygmiiiEN)Vr;8Su^m~I6+v4py zJ5}lV(8LR>ZX`K`NyEp3H4SpkNQg8d40~(qvt@&ozX8v`wct)X zF=kotI5PdGxZdAMQhSNx+!Hu}qiGh%ovB8!OarLe2%Z?cEd^N#T1mD!PT)m&`e7-=Vc$CD3RmWl_oW@%!xp8G3qwb}?{l)r&~FZ<2_wepPC%Eda^K+8QN8Y-TmKaNJjG*vEIC%B$% zBvXWI|(G#n4ZNzmai@Sp$Giwm$rl#axYPF z4nJwHfBdR%(ikzVq6fr{chBL1!aHck!)f~E+>vhSRL=~mt({0Go2p-GPHAtmbo@A7 zu0Ifq*ew#A0QibYCx|90cO{%rMtwR4fGPT^LxnqwL-|q@9FV3ZV|^6Dxcr9oZmh!x z7&Rd@@U`0>bTO;^WS5hniN)|w#58CXI_zS~@V zlgvBeb^}_R7Tl;NpSbhR)~1L+`NnzFvmk_4tilo!$- zki0&?>6$}L|E}cg*Y-#mvk8t~g-+UnuUS)r;q7Zw`vlHVta?kHcQ8A~rw?-@?>W|W zp3p&0<4reK$u|B`!>NM#K=FG3`7%FyN1@=v*YZ9fYaNpW`P+l0A*X#tZ`@yD0JCJ^0w@h#)@I9LOfzMQxMfWx*w8CCN;CPBbl~J?`sLUG2HU_WgLa z`UfiJQn%4^W#GETNwEAQr5ysv1?c+dN{Ixq1=b+x`Z&H31ThlFHV;(>ptYk0-q$b#!`G-aQZj{jg{ z-HsE)rF7}~4-DvCuwdL9p~n6rtw^%tX0`yg+Bu7rODNi(M>&Kf{Fy54wV*=$jkMbdAjeI?3lEH2K{wu@D%_IC45biRIS0@7x3&K6Vil+CKN zq;4M`?l4=V(TQl_UEzAXzqjfe`HY`LEt@ftxDIH0gJPiTZ4jgjRr5@YxK+9VD$Vs=x3z9tT}g|^T)Gx@%8mswXSmKljWjJxJ4so<29 zG1)5-s&xwCcB(7o(PDv3zXAkT0iez`3ht@!UI`=xu3;?{nfBjiOi6 zL(uj&%opu_k?AsO9>8lbBM*bWo)uo_gKd&pA!N6zfcjcadt&8V9P%K|GPhz(6&*?O z3nBTFPj{@$4SFY-rS-P9l@-0zGFZj)G3fJG`oU--hedk)1PI z4_S%IX1e=|H5|~o7cwr6Z?0&>Hwq`Id_@lEJ z8YEg8j1{igU7063lZpeoJDL~zq6zW*qzLI(#MRN85-K6N*Yj>HU`>T9#LPae=LmOA zUd~RXNDm1jx@rH&gzqtx`wN{Kl~ti8{uM~;E$ZJ0$^lO-m5jMg1>z8rT=0C$I9Kye zTk!-wA)~ZY^^Vg(jCf zWy2bx984g#6EI3$AgYQ-)NfMkl!|FxDbk0k%U8G z3Dcyx8P*jv)96-?n5>rzAd2Xw&zi zgDA7?&O}&633yf-xa?LiH_U)?dnbRw9Toa&rjz6%6zIybXjyUfs(o!0y2?U&OkKKE zc9_qZYn@WW8f_Wh`mzZ?$?zEnfWSspSm2RXnP=d~)~3;2B)3Jc-Qb>k5CpnWRZgl9 zM(r!E8~M2YTiz|*u$r{}B^bh{kIB_hnc4BcY44;-c~Jb+OYQy4$uyvTOM1-lqtgFS z;?y7$9eco95wNvhiBa0kY2CCLS;&W!8#k=%RW35Ub5hqEg6a~IK8dE6ZP4b%*l{N}Xlz``kV@nngsC@|R~ zd8 zRpC`Y0he9@p}PiRxUq2seU0P_HKNI0<7aB^4C2^oA4UVRv-G&!##?H6YP^!^^x6$N zQ4JTheH%D2ky>)G8qUPmTBlUyyhtr^NO-g_tyj`PKSf6ff$PyFVrz$AJS{+EIe?bW z22kAS;bob^(jc<|*+7Y~$l24_>kXu(W{1iC?Y)W~=I4GY#gv`A==0ZHLd`M?j7Tr; z54`x+yyt%yJKG@G&D_0YyJ$qLlbi!w>tb^eEaDkftzNiW_Uc%JRn3i(sj9qnfilYE zj{c4^{6UGk#nwnv3Ig)SLC9(eUWsUOn1JqSwRKn8Q}FP8u61wWGn2|2(w7$-Tw~ic z-m-T4&P*(c3VR_?jFWm$Rnc+#g9PE1I{{y$Mvj%x&`4D?U2*Z2B1o0ohW?z={DWkZVQ)g7VTF6O%WjjmhfT<14O}r%RIadsG##2XAs90(UcsjvdJO z#a2d`AQV*MB>k_-0kzNq0n#nNG5d%9^ob@l+RZTWUrR^{ zTd-=uRBw1|vDPuc!H3k)Y!C7}zd12&7=f+v;BsT$V0AnN+jEyi)wwn^XrQ)VEAU>k zGAR>7aUH`v4>V3(u~{$~MSFqB-?o9z8Jyv^H|CU;pl=XR>{+gLfnc>p0;J~Utm71_ z!1Q~S!v>-9_Pg%2Q{r|cO3E3fQ-iKxSk|;p(_ruYw-*wV(a#+comAUw&dw*ZE}htHvmG|+fC!#Q&T^y8II6dvx!9bFRwBkz-#rk(=z=Jm;lf(RA2D6 zmJA8(1D0FFBEAi%A{H28-~?Vwvk2D~Ff(Qv)G`blWV%=wvhKYE<;!7X++X|TSuPg` zMi+UPK+!eC2kQbaJ(07PQv-ecSQ_@EvB}lS{$8kZyDh%Ti7^lqH#e^q_Pkn-Z=-yE zXgH!U&cDr)f`aW|z}IR-{)5XMT#%A~*uJx_PAbUMDTw1|JXB3T*V=QWL*|D)%m0^%RbvFj}+#x-9Ysza-9P23r>EWyUUmj9DLE| z*-G0STjy9fsuJEx+k{QIU25#OnGGS1wjK`@78y z*Wi{rXBR@m6rM253%mnEw&QnKQeNLqxiwu{U|Hbt0&oub9=J4b$U=w}CB#wAP>cJf zx~#+rlxJLKgzA?k8nwcM8KZX3$$@SY(6+jiA`({{FB z8#7^G49Tb($)QblaZIPi=@$|@@`6k0`4ql*?x3bQ00NpU zJ8Wnp9BKJ#WD9YMyBdH(f&A8THW!X7mq`1xJk@ViQ9UOSaD!^KzkclAW|Qgc-9Y>( ziNH=}K(7rgzFX*BY35KxP{fnpXDfbEyn|c>EMaq9t$N3sufKaR7@r&_CB8jxygF#( zHd@^Qx3A8RLl7rF^cc+!%o)!yUR_rAicC^`e!n@AmPehl4YKD#|U9uVjB=E{y3@lKpDPi*b zVcAt+ys@dUgQW!|CyI5s5M~MUrS>%|^Nr%WSvyG?U>J@pKM54Yf4Q6d=3Z1!QbOWg zPv<-i;Mm#L)(eXE-eqoMbz_*e(swh3BOyy~+m&dPrsP^m9pb4K7AayolTz^}awYj( z$OnX>i3D5uv04|ta8P9ewU*SND!FiEDoegcEIN(F&f){{g5O}FN4m^}@dM|IMC9f49!H)JZH}a}7XyB` z*Z5f|P>k?O=MEq1X359zfhI3J(kgIB$*KPkAGW&~*45WI)4{uwDlvMkHuh%sWPOgK znP3%|Thfjg$?LPf(zQ@VgYI*mTLk<%zjQb*ayiU+seQ!Yid&I$5Df1>QEAJa=4g z(u(4m7*YZ6c{-^MdyX5bpeVQ`bT1RLv?%Re$`(u~Ne~z_>0OaiM%`u8Hnw3i4ps&x zB+X34oR4F9Z&admD`?sGif9R>RxO0Aw)gOo8LIslonnyY)$!#jY0#lBDoa+q)Q7%t z`tTTkz%_ly634D5atLs-jgR^Wlijp_H;D$f*L3-!P@{4JJM!n-CV$F8r^B=q@xzd_ z0fS}C;hg!h+D|~UcS`&ZG@__U^EN!J@?ydn4Fv>9F%$b;l|Dn8eijx-Jaq0ZiQ6gT z-a>Sqi($5R#Jrt;%`5+~j{oAH|9(e(dNIq)HE?rJuyZBySfYrelG-@zp7PBZsyndA z1Vh;b%Xyn*@N1JXtTed5zz4E>%ECBwY*a5&W#H0}Ue;f}W7f&gx0no0SbOfH)^6LR z<-;kSNIUK?2KN6*p#CJK!5lkQEN=J-XtKW(zo~qJJSDdY$HbO6nQpol3AdXfY_zmy zFFaEYA|Z#}M$ZE8TQ2uXzv2tMQ{$Xy_)DC8N6c#F6Nb44}*=Qi%&HuX#I8@|HA%Xt2?RDaj?7W5ZpH4n2tr ze#Q8m>40Zagy>q{XIfan8&PwHgP|dxl1HnCyIK=rjjjRd4*j03spXJP?h7x^)uHIFb_YeM=O7 zWNv;o6~=)~>`q0XS@>$fUavkObCvA*>0%H^(wlabq`F7yAP4zB|KxjPI-QR- z;m+;bQ9BFPqn;VQ^;dfL20Uu*h&T2hQCN?NZyHJcbW88=xplQ@1B1a0iMK|@e`Jb( z@@fqyRs6u}&8BJ@5$weJ?H84QPw>C^v@1z%T|>z{*AQucbmP+7UsB0m#QE#Lh6Y`v z&LN&LxaQy}vW4K%IS2p$xhWhfc0{K0kFxx{(;JKc|uLuJbGJgBrNw4g=P&mhD)p@ z(QtoctArE#4FcRUztH`k)(Jg*m^z!kx64o`Lk)LahcXlJbjq*q zCx_OG>smKk536;2u`KWVGA!VtvSs5M8;bo63aHS?Wv1PhYecV$w4|hSrjt@%zXtYG%tIk=)0zSj$|wHGtK;!BilV= zJvM@TZxLm2s_4z`b)HFS*n8pMbMy-RsxKpPIW#H3p!(^FqR-cVGgKEudrNbvQDE?N zR{#0mjG;;Z1@_$SV>mGNh2OCzlV+-^Dy31;0vxY1F|7h541oKt{r+Enb)wy~y86aK z7e1bk=uX$Y8@;pc7d^LqQ|Srd+oPW@5qr3|;c6Kv)|S{w6rKqlIT zp+rHj^52;VzhuQM$`L1yxh5t55=dL?i9hv)zE&eCRafKe1jgYB>GRWQd#$TY*r6a| z`H5feem+@^zh*qmpvq0q8;a68?FKOIzI;CBU%E$)j^ko!G}q+QXjhML#3Pp&Q8{7Eo52rQ4%q`)sYh!Gd4qWbMoE@}N|fmLT6q;i7^x zn9a?Apu$9u;b4-6%1-`!6-IA0|&opEq$ z>-cY&-{~5y-)4o_NM!0lI)_tda(Q_gQE}vQ4n89)L?+>(lrbrT#@?!J&#?Y>jwH_J0BCYbkx*ABTe4qmJQj_g6nm ze&Z5$h}q}#L`4+`caoC_C@)Dy=#~5vHDbgz>x|P0H7bFg4;#S}ArEcd$++mB*XEUf z{Yje_Gxg-oUa8(IqI}cYiJ}MfN#FI6ztGrPm`PD4gOV?XJ({_)V<+AfGJAKp* z=jC&b%Vzd~W%Af4%AWX zH>pX^)%2V2e;xO~G!ZCj&HW8o2Pq$Ft@Sb!GHcUP`q$VvJZ;o5gahxO(}=iCBbrvw zcbs-Yi#Oq(rpeiG_-$BxgYs0bFj<|-F8#~_M!DO9lHqXWi4QvR7eY=_FW$h^4vq~* ztzrE>Q2Vc{PAOPm5LC)wqTp{Eo^q!DH7R|j^*bTWoFs^@`YI;FiL>HdEcdx+FnZ45 z-?}Pvock_)jcWiX&^kM540cx(yrO)iIQTlE=4+ z_2eEHQ)*qH1&$)D4-u4wU7*3qK1K|I$`6=d1(4i*^<@4Fpr4^Jc!>rsXF4P2y7oCm zS*&<$xKJMS{p3IBywH5+>iamZX=CH8CT!5Fk6mFCNSOjq;2z=Vh(&%qAM{Ux%)L#6 zH}&0Bwfy84a}8=l68Sb;RM;wD=srU264_m_=!zkAOg`Ede3p{)IQHj#{15D|20mUY zbyO(<#miYgW99UkTKUwkUTvT6uYv{KJ^I{-E83;v{D-?hulDK zaop4}KHbLZH*2XGFsy|+TGY~|q*J_jVEK6V)t?Fxs4J)(IbU8QqCT|RKa?Kq^+EFc zs`W<$Oi-Iu-UiFu)W(pF`QP#v{O|3ko{*L3W&Jlkzr!-?<&n|uF)2PPc>V{v#6q#%X9RwG%kVGOg$>pU~ClS$K+P>rS`HPZzrXBACGlwR-dM zuB4E`FACO~zkwx{>*wDcqWb*-kCspVa);jmhrN?Af}2zz{eBV|a~j%-&5a36QGEGx z{<(;Ix7ibaO&V&=C)P_|?Xepu5nKR*2Zw3{aeDzB~WG&93)*k{u_0e~P$F>ZD5xftPeJ5B!LA z*Oh#J*KS8hID_~rvHgF)t2sgSDCLU{0J3t4=}PAf{Osv|O<7LWvb&MX`sasP@|MfMJ&^2ayiBpaZ z->w77-U;{%WS*@3&9wk3{M24D9QNqF>LJ{X66YnxYmzj~k1_UmCKY)^8EaY-s;Q z-~W-;xmQE=lVn{B>5_4|8!rtl&kcYdQtyiVAj<#wYnqyk2~X2k*6c+qc9`mf_Hp9s zw)*3no3c|1gx}n{XHm<_$`UY-D%?2J;&!|umnJQQ_4lq*XdU~-LT-7kj` zOLSx5RZ>&V+tAKBu*!(qeqO{OdOAp{q@%3WJ9|oj2+$mXCgi;vGqQ6bp#a)6BDrY0|LL3 zi-%}^4YIx}W@z3?tqpoY4XV*f{-L~$J;7`NtIAU!4M#ENY;HeW;r`A4$2oh&n!dj0 tnJ3#idsjrdfOG7b$?p$!{Mq4s)$ue8_R(qP;X~9P&D#%d72mWD`# Date: Wed, 8 Apr 2020 15:14:07 +0200 Subject: [PATCH 04/40] skips 'Sorts by activated rules' (#62924) --- .../siem/cypress/integration/signal_detection_rules.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/legacy/plugins/siem/cypress/integration/signal_detection_rules.spec.ts b/x-pack/legacy/plugins/siem/cypress/integration/signal_detection_rules.spec.ts index 1559285d508ed..2d2db9e70255b 100644 --- a/x-pack/legacy/plugins/siem/cypress/integration/signal_detection_rules.spec.ts +++ b/x-pack/legacy/plugins/siem/cypress/integration/signal_detection_rules.spec.ts @@ -32,7 +32,7 @@ describe('Signal detection rules', () => { esArchiverUnload('prebuilt_rules_loaded'); }); - it('Sorts by activated rules', () => { + it.skip('Sorts by activated rules', () => { loginAndWaitForPageWithoutDateRange(DETECTIONS); goToManageSignalDetectionRules(); waitForLoadElasticPrebuiltDetectionRulesTableToBeLoaded(); From 4d7cc6dfb787b10dd3c32b8f90b95bd948920076 Mon Sep 17 00:00:00 2001 From: Maja Grubic Date: Wed, 8 Apr 2020 14:32:13 +0100 Subject: [PATCH 05/40] Removing unused import (#62917) Co-authored-by: Elastic Machine --- .../embeddable/public/lib/embeddables/error_embeddable.test.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/plugins/embeddable/public/lib/embeddables/error_embeddable.test.tsx b/src/plugins/embeddable/public/lib/embeddables/error_embeddable.test.tsx index 816001ba42ff1..715827a72c61b 100644 --- a/src/plugins/embeddable/public/lib/embeddables/error_embeddable.test.tsx +++ b/src/plugins/embeddable/public/lib/embeddables/error_embeddable.test.tsx @@ -20,8 +20,6 @@ import React from 'react'; import { ErrorEmbeddable } from './error_embeddable'; import { EmbeddableRoot } from './embeddable_root'; import { mount } from 'enzyme'; -// @ts-ignore -import { findTestSubject } from '@elastic/eui/lib/test'; test('ErrorEmbeddable renders an embeddable', async () => { const embeddable = new ErrorEmbeddable('some error occurred', { id: '123', title: 'Error' }); From 6b52ce7341e52bdb1cce4b1fb90181c03fc74f5e Mon Sep 17 00:00:00 2001 From: James Gowdy Date: Wed, 8 Apr 2020 15:09:56 +0100 Subject: [PATCH 06/40] [ML] Adding configurable file size to file data visualizer (#62752) * [ML] Adding configurable file size to file data visualizer * updating translated strings --- .../ml/common/constants/file_datavisualizer.ts | 2 ++ x-pack/plugins/ml/common/types/ml_config.ts | 16 ++++++++++++++++ x-pack/plugins/ml/public/application/app.tsx | 7 ++++++- .../datavisualizer/datavisualizer_selector.tsx | 6 +++++- .../components/about_panel/welcome_content.tsx | 6 +++++- .../file_datavisualizer_view.js | 13 +++++++------ .../file_error_callouts.tsx | 7 +++---- .../file_based/components/utils/index.ts | 2 ++ .../file_based/components/utils/utils.ts | 15 +++++++++++++++ .../public/application/util/dependency_cache.ts | 11 +++++++++++ x-pack/plugins/ml/public/index.ts | 4 ++-- x-pack/plugins/ml/public/plugin.ts | 13 ++++++++++++- x-pack/plugins/ml/server/config.ts | 15 +++++++++++++++ x-pack/plugins/ml/server/index.ts | 2 ++ .../plugins/translations/translations/ja-JP.json | 2 -- .../plugins/translations/translations/zh-CN.json | 2 -- 16 files changed, 103 insertions(+), 20 deletions(-) create mode 100644 x-pack/plugins/ml/common/types/ml_config.ts create mode 100644 x-pack/plugins/ml/server/config.ts diff --git a/x-pack/plugins/ml/common/constants/file_datavisualizer.ts b/x-pack/plugins/ml/common/constants/file_datavisualizer.ts index d72e4d63cc47e..81d51bfa25816 100644 --- a/x-pack/plugins/ml/common/constants/file_datavisualizer.ts +++ b/x-pack/plugins/ml/common/constants/file_datavisualizer.ts @@ -5,6 +5,8 @@ */ export const MAX_BYTES = 104857600; +export const ABSOLUTE_MAX_BYTES = MAX_BYTES * 5; +export const FILE_SIZE_DISPLAY_FORMAT = '0,0.[0] b'; // Value to use in the Elasticsearch index mapping meta data to identify the // index as having been created by the ML File Data Visualizer. diff --git a/x-pack/plugins/ml/common/types/ml_config.ts b/x-pack/plugins/ml/common/types/ml_config.ts new file mode 100644 index 0000000000000..8fd9fd22bad8a --- /dev/null +++ b/x-pack/plugins/ml/common/types/ml_config.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 { schema, TypeOf } from '@kbn/config-schema'; +import { MAX_BYTES } from '../constants/file_datavisualizer'; + +export const configSchema = schema.object({ + file_data_visualizer: schema.object({ + max_file_size_bytes: schema.number({ defaultValue: MAX_BYTES }), + }), +}); + +export type MlConfigType = TypeOf; diff --git a/x-pack/plugins/ml/public/application/app.tsx b/x-pack/plugins/ml/public/application/app.tsx index e9796fcbb0fe4..f1facd18b9da5 100644 --- a/x-pack/plugins/ml/public/application/app.tsx +++ b/x-pack/plugins/ml/public/application/app.tsx @@ -15,10 +15,14 @@ import { KibanaContextProvider } from '../../../../../src/plugins/kibana_react/p import { setDependencyCache, clearCache } from './util/dependency_cache'; import { setLicenseCache } from './license'; import { MlSetupDependencies, MlStartDependencies } from '../plugin'; +import { MlConfigType } from '../../common/types/ml_config'; import { MlRouter } from './routing'; -type MlDependencies = MlSetupDependencies & MlStartDependencies; +type MlDependencies = MlSetupDependencies & + MlStartDependencies & { + mlConfig: MlConfigType; + }; interface AppProps { coreStart: CoreStart; @@ -74,6 +78,7 @@ export const renderApp = ( http: coreStart.http, security: deps.security, urlGenerators: deps.share.urlGenerators, + mlConfig: deps.mlConfig, }); const mlLicense = setLicenseCache(deps.licensing); diff --git a/x-pack/plugins/ml/public/application/datavisualizer/datavisualizer_selector.tsx b/x-pack/plugins/ml/public/application/datavisualizer/datavisualizer_selector.tsx index a8bb5a0a8fe10..2d6505f5ce1f7 100644 --- a/x-pack/plugins/ml/public/application/datavisualizer/datavisualizer_selector.tsx +++ b/x-pack/plugins/ml/public/application/datavisualizer/datavisualizer_selector.tsx @@ -26,6 +26,7 @@ import { isFullLicense } from '../license'; import { useTimefilter, useMlKibana } from '../contexts/kibana'; import { NavigationMenu } from '../components/navigation_menu'; +import { getMaxBytesFormatted } from './file_based/components/utils'; function startTrialDescription() { return ( @@ -59,6 +60,8 @@ export const DatavisualizerSelector: FC = () => { licenseManagement.enabled === true && isFullLicense() === false; + const maxFileSize = getMaxBytesFormatted(); + return ( @@ -102,7 +105,8 @@ export const DatavisualizerSelector: FC = () => { description={ } betaBadgeLabel={i18n.translate( diff --git a/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/about_panel/welcome_content.tsx b/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/about_panel/welcome_content.tsx index c56ab021e2f2f..49b2396aeca13 100644 --- a/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/about_panel/welcome_content.tsx +++ b/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/about_panel/welcome_content.tsx @@ -19,6 +19,7 @@ import { } from '@elastic/eui'; import { ExperimentalBadge } from '../experimental_badge'; +import { getMaxBytesFormatted } from '../utils'; export const WelcomeContent: FC = () => { const toolTipContent = i18n.translate( @@ -28,6 +29,8 @@ export const WelcomeContent: FC = () => { } ); + const maxFileSize = getMaxBytesFormatted(); + return ( @@ -117,7 +120,8 @@ export const WelcomeContent: FC = () => {

diff --git a/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/file_datavisualizer_view/file_datavisualizer_view.js b/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/file_datavisualizer_view/file_datavisualizer_view.js index 02f14a9e4553e..d1b615a878b2b 100644 --- a/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/file_datavisualizer_view/file_datavisualizer_view.js +++ b/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/file_datavisualizer_view/file_datavisualizer_view.js @@ -19,14 +19,15 @@ import { FileCouldNotBeRead, FileTooLarge } from './file_error_callouts'; import { EditFlyout } from '../edit_flyout'; import { ExplanationFlyout } from '../explanation_flyout'; import { ImportView } from '../import_view'; -import { MAX_BYTES } from '../../../../../../common/constants/file_datavisualizer'; import { + getMaxBytes, readFile, createUrlOverrides, processResults, reduceData, hasImportPermission, } from '../utils'; + import { MODE } from './constants'; const UPLOAD_SIZE_MB = 5; @@ -57,6 +58,7 @@ export class FileDataVisualizerView extends Component { this.overrides = {}; this.previousOverrides = {}; this.originalSettings = {}; + this.maxFileUploadBytes = getMaxBytes(); } async componentDidMount() { @@ -93,7 +95,7 @@ export class FileDataVisualizerView extends Component { }; async loadFile(file) { - if (file.size <= MAX_BYTES) { + if (file.size <= this.maxFileUploadBytes) { try { const fileContents = await readFile(file); const data = fileContents.data; @@ -105,7 +107,6 @@ export class FileDataVisualizerView extends Component { await this.loadSettings(data); } catch (error) { - console.error(error); this.setState({ loaded: false, loading: false, @@ -181,8 +182,6 @@ export class FileDataVisualizerView extends Component { fileCouldNotBeRead: isRetry, }); } catch (error) { - console.error(error); - this.setState({ results: undefined, explanation: undefined, @@ -287,7 +286,9 @@ export class FileDataVisualizerView extends Component { {loading && } - {fileTooLarge && } + {fileTooLarge && ( + + )} {fileCouldNotBeRead && loading === false && ( diff --git a/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/file_datavisualizer_view/file_error_callouts.tsx b/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/file_datavisualizer_view/file_error_callouts.tsx index 3dbc20f16012b..7333c96a0d8ea 100644 --- a/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/file_datavisualizer_view/file_error_callouts.tsx +++ b/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/file_datavisualizer_view/file_error_callouts.tsx @@ -11,8 +11,7 @@ import { EuiCallOut, EuiSpacer } from '@elastic/eui'; import numeral from '@elastic/numeral'; import { ErrorResponse } from '../../../../../../common/types/errors'; - -const FILE_SIZE_DISPLAY_FORMAT = '0,0.[0] b'; +import { FILE_SIZE_DISPLAY_FORMAT } from '../../../../../../common/constants/file_datavisualizer'; interface FileTooLargeProps { fileSize: number; @@ -81,7 +80,7 @@ interface FileCouldNotBeReadProps { } export const FileCouldNotBeRead: FC = ({ error, loaded }) => { - const message = error.body.message; + const message = error?.body?.message || ''; return ( = ({ error, loaded }; export const Explanation: FC<{ error: ErrorResponse }> = ({ error }) => { - if (!error.body.attributes?.body?.error?.suppressed?.length) { + if (!error?.body?.attributes?.body?.error?.suppressed?.length) { return null; } const reason: string = error.body.attributes.body.error.suppressed[0].reason; diff --git a/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/utils/index.ts b/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/utils/index.ts index 6f670359586b7..0f0036a7c4616 100644 --- a/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/utils/index.ts +++ b/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/utils/index.ts @@ -10,4 +10,6 @@ export { processResults, readFile, reduceData, + getMaxBytes, + getMaxBytesFormatted, } from './utils'; diff --git a/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/utils/utils.ts b/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/utils/utils.ts index 5048065ae60fa..0d2016b71ed83 100644 --- a/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/utils/utils.ts +++ b/x-pack/plugins/ml/public/application/datavisualizer/file_based/components/utils/utils.ts @@ -5,8 +5,14 @@ */ import { isEqual } from 'lodash'; +import numeral from '@elastic/numeral'; import { ml } from '../../../../services/ml_api_service'; import { AnalysisResult, InputOverrides } from '../../../../../../common/types/file_datavisualizer'; +import { + ABSOLUTE_MAX_BYTES, + FILE_SIZE_DISPLAY_FORMAT, +} from '../../../../../../common/constants/file_datavisualizer'; +import { getMlConfig } from '../../../../util/dependency_cache'; const DEFAULT_LINES_TO_SAMPLE = 1000; @@ -54,6 +60,15 @@ export function reduceData(data: string, mb: number) { return data.length >= size ? data.slice(0, size) : data; } +export function getMaxBytes() { + const maxBytes = getMlConfig().file_data_visualizer.max_file_size_bytes; + return maxBytes < ABSOLUTE_MAX_BYTES ? maxBytes : ABSOLUTE_MAX_BYTES; +} + +export function getMaxBytesFormatted() { + return numeral(getMaxBytes()).format(FILE_SIZE_DISPLAY_FORMAT); +} + export function createUrlOverrides(overrides: InputOverrides, originalSettings: InputOverrides) { const formattedOverrides: InputOverrides = {}; for (const o in overrideDefaults) { diff --git a/x-pack/plugins/ml/public/application/util/dependency_cache.ts b/x-pack/plugins/ml/public/application/util/dependency_cache.ts index d5605d3bca65f..934a0a5e9ae3a 100644 --- a/x-pack/plugins/ml/public/application/util/dependency_cache.ts +++ b/x-pack/plugins/ml/public/application/util/dependency_cache.ts @@ -23,6 +23,7 @@ import { } from 'kibana/public'; import { SharePluginStart } from 'src/plugins/share/public'; import { SecurityPluginSetup } from '../../../../security/public'; +import { MlConfigType } from '../../../common/types/ml_config'; export interface DependencyCache { timefilter: DataPublicPluginSetup['query']['timefilter'] | null; @@ -42,6 +43,7 @@ export interface DependencyCache { security: SecurityPluginSetup | null; i18n: I18nStart | null; urlGenerators: SharePluginStart['urlGenerators'] | null; + mlConfig: MlConfigType | null; } const cache: DependencyCache = { @@ -62,6 +64,7 @@ const cache: DependencyCache = { security: null, i18n: null, urlGenerators: null, + mlConfig: null, }; export function setDependencyCache(deps: Partial) { @@ -82,6 +85,7 @@ export function setDependencyCache(deps: Partial) { cache.security = deps.security || null; cache.i18n = deps.i18n || null; cache.urlGenerators = deps.urlGenerators || null; + cache.mlConfig = deps.mlConfig || null; } export function getTimefilter() { @@ -202,6 +206,13 @@ export function getGetUrlGenerator() { return cache.urlGenerators.getUrlGenerator; } +export function getMlConfig() { + if (cache.mlConfig === null) { + throw new Error("mlConfig hasn't been initialized"); + } + return cache.mlConfig; +} + export function clearCache() { console.log('clearing dependency cache'); // eslint-disable-line no-console Object.keys(cache).forEach(k => { diff --git a/x-pack/plugins/ml/public/index.ts b/x-pack/plugins/ml/public/index.ts index 8070f94a1264d..4697496270edf 100755 --- a/x-pack/plugins/ml/public/index.ts +++ b/x-pack/plugins/ml/public/index.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { PluginInitializer } from 'kibana/public'; +import { PluginInitializer, PluginInitializerContext } from 'kibana/public'; import './index.scss'; import { MlPlugin, @@ -19,6 +19,6 @@ export const plugin: PluginInitializer< MlPluginStart, MlSetupDependencies, MlStartDependencies -> = () => new MlPlugin(); +> = (context: PluginInitializerContext) => new MlPlugin(context); export { MlPluginSetup, MlPluginStart }; diff --git a/x-pack/plugins/ml/public/plugin.ts b/x-pack/plugins/ml/public/plugin.ts index 2472c343d0510..b51be4d248683 100644 --- a/x-pack/plugins/ml/public/plugin.ts +++ b/x-pack/plugins/ml/public/plugin.ts @@ -5,7 +5,13 @@ */ import { i18n } from '@kbn/i18n'; -import { Plugin, CoreStart, CoreSetup, AppMountParameters } from 'kibana/public'; +import { + Plugin, + CoreStart, + CoreSetup, + AppMountParameters, + PluginInitializerContext, +} from 'kibana/public'; import { ManagementSetup } from 'src/plugins/management/public'; import { SharePluginStart } from 'src/plugins/share/public'; import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; @@ -19,6 +25,7 @@ import { LicenseManagementUIPluginSetup } from '../../license_management/public' import { setDependencyCache } from './application/util/dependency_cache'; import { PLUGIN_ID, PLUGIN_ICON } from '../common/constants/app'; import { registerFeature } from './register_feature'; +import { MlConfigType } from '../common/types/ml_config'; export interface MlStartDependencies { data: DataPublicPluginStart; @@ -34,7 +41,10 @@ export interface MlSetupDependencies { } export class MlPlugin implements Plugin { + constructor(private readonly initializerContext: PluginInitializerContext) {} + setup(core: CoreSetup, pluginsSetup: MlSetupDependencies) { + const mlConfig = this.initializerContext.config.get(); core.application.register({ id: PLUGIN_ID, title: i18n.translate('xpack.ml.plugin.title', { @@ -57,6 +67,7 @@ export class MlPlugin implements Plugin { usageCollection: pluginsSetup.usageCollection, licenseManagement: pluginsSetup.licenseManagement, home: pluginsSetup.home, + mlConfig, }, { element: params.element, diff --git a/x-pack/plugins/ml/server/config.ts b/x-pack/plugins/ml/server/config.ts new file mode 100644 index 0000000000000..7cef6f17bbefb --- /dev/null +++ b/x-pack/plugins/ml/server/config.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 { PluginConfigDescriptor } from 'kibana/server'; +import { MlConfigType, configSchema } from '../common/types/ml_config'; + +export const config: PluginConfigDescriptor = { + exposeToBrowser: { + file_data_visualizer: true, + }, + schema: configSchema, +}; diff --git a/x-pack/plugins/ml/server/index.ts b/x-pack/plugins/ml/server/index.ts index 175c20bf49c94..6e638d647a387 100644 --- a/x-pack/plugins/ml/server/index.ts +++ b/x-pack/plugins/ml/server/index.ts @@ -9,3 +9,5 @@ import { MlServerPlugin } from './plugin'; export { MlPluginSetup, MlPluginStart } from './plugin'; export const plugin = (ctx: PluginInitializerContext) => new MlServerPlugin(ctx); + +export { config } from './config'; diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 2ae29202ede43..d07026c0883b8 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -9732,7 +9732,6 @@ "xpack.ml.datavisualizer.selector.dataVisualizerTitle": "データビジュアライザー", "xpack.ml.datavisualizer.selector.experimentalBadgeLabel": "実験的", "xpack.ml.datavisualizer.selector.experimentalBadgeTooltipLabel": "実験的機能。フィードバックをお待ちしています。", - "xpack.ml.datavisualizer.selector.importDataDescription": "ログファイルからデータをインポートします。最大 100 MB のファイルをアップロードできます。", "xpack.ml.datavisualizer.selector.importDataTitle": "データのインポート", "xpack.ml.datavisualizer.selector.selectIndexButtonLabel": "インデックスを選択", "xpack.ml.datavisualizer.selector.selectIndexPatternDescription": "既存の Elasticsearch インデックスのデータを可視化します。", @@ -9983,7 +9982,6 @@ "xpack.ml.fileDatavisualizer.welcomeContent.logFilesWithCommonFormatDescription": "タイムスタンプの一般的フォーマットのログファイル", "xpack.ml.fileDatavisualizer.welcomeContent.newlineDelimitedJsonDescription": "改行区切りの JSON", "xpack.ml.fileDatavisualizer.welcomeContent.supportedFileFormatDescription": "ファイルデータビジュアライザーはこれらのファイル形式をサポートしています:", - "xpack.ml.fileDatavisualizer.welcomeContent.uploadedFilesAllowedSizeDescription": "最大 100 MB のファイルをアップロードできます。", "xpack.ml.fileDatavisualizer.welcomeContent.visualizeDataFromLogFileDescription": "ファイルデータビジュアライザーは、ログファイルのフィールドとメトリックの理解に役立ちます。ファイルをアップロードして、データを分析し、 Elasticsearch インデックスにインポートするか選択できます。", "xpack.ml.fileDatavisualizer.welcomeContent.visualizeDataFromLogFileTitle": "ログファイルのデータを可視化 {experimentalBadge}", "xpack.ml.formatters.metricChangeDescription.actualSameAsTypicalDescription": "実際値が通常値と同じ", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 7f5df15dec83a..7e64ff6301faf 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -9735,7 +9735,6 @@ "xpack.ml.datavisualizer.selector.dataVisualizerTitle": "数据可视化工具", "xpack.ml.datavisualizer.selector.experimentalBadgeLabel": "实验性", "xpack.ml.datavisualizer.selector.experimentalBadgeTooltipLabel": "实验功能。我们很乐意听取您的反馈意见。", - "xpack.ml.datavisualizer.selector.importDataDescription": "从日志文件导入数据。您可以上传最大 100 MB 的文件。", "xpack.ml.datavisualizer.selector.importDataTitle": "导入数据", "xpack.ml.datavisualizer.selector.selectIndexButtonLabel": "选择索引", "xpack.ml.datavisualizer.selector.selectIndexPatternDescription": "可视化现有 Elasticsearch 索引中的数据。", @@ -9986,7 +9985,6 @@ "xpack.ml.fileDatavisualizer.welcomeContent.logFilesWithCommonFormatDescription": "具有时间戳通用格式的日志文件", "xpack.ml.fileDatavisualizer.welcomeContent.newlineDelimitedJsonDescription": "换行符分隔的 JSON", "xpack.ml.fileDatavisualizer.welcomeContent.supportedFileFormatDescription": "File Data Visualizer 支持以下文件格式:", - "xpack.ml.fileDatavisualizer.welcomeContent.uploadedFilesAllowedSizeDescription": "您可以上传最大 100 MB 的文件。", "xpack.ml.fileDatavisualizer.welcomeContent.visualizeDataFromLogFileDescription": "File Data Visualizer 可帮助您理解日志文件中的字段和指标。上传文件、分析文件数据,然后选择是否将数据导入 Elasticsearch 索引。", "xpack.ml.fileDatavisualizer.welcomeContent.visualizeDataFromLogFileTitle": "可视化来自日志文件的数据 {experimentalBadge}", "xpack.ml.formatters.metricChangeDescription.actualSameAsTypicalDescription": "实际上与典型模式相同", From 67536e4b3cda294dae60e4f5e013e3afcfc4d1fd Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Wed, 8 Apr 2020 08:12:37 -0600 Subject: [PATCH 07/40] =?UTF-8?q?Fix=20issue=20with=20license=20not=20gett?= =?UTF-8?q?ing=20obtained=20&=20passed=20to=20server=E2=80=A6=20(#62883)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- x-pack/legacy/plugins/tilemap/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/legacy/plugins/tilemap/index.js b/x-pack/legacy/plugins/tilemap/index.js index 767a0fe72985e..d4105519ee0a7 100644 --- a/x-pack/legacy/plugins/tilemap/index.js +++ b/x-pack/legacy/plugins/tilemap/index.js @@ -15,7 +15,7 @@ export const tilemap = kibana => { require: ['xpack_main', 'vis_type_vislib'], publicDir: resolve(__dirname, 'public'), uiExports: { - visTypeEnhancers: ['plugins/tilemap/vis_type_enhancers/update_tilemap_settings'], + hacks: ['plugins/tilemap/vis_type_enhancers/update_tilemap_settings'], }, init: function(server) { const thisPlugin = this; From d94d7cc7195870c9c7379062684c0adbf2a5e73b Mon Sep 17 00:00:00 2001 From: Poff Poffenberger Date: Wed, 8 Apr 2020 09:20:25 -0500 Subject: [PATCH 08/40] [Canvas] Fix Canvas-specific storybook after new platform changes (#61876) * Fix Canvas storybook webpack config * Temporarily disable workpad export example * Mock out lib/notify and download_workpad Co-authored-by: Elastic Machine --- .../canvas/.storybook/webpack.config.js | 27 ++++++++++++++++--- .../canvas/tasks/mocks/downloadWorkpad.js | 13 +++++++++ 2 files changed, 36 insertions(+), 4 deletions(-) create mode 100644 x-pack/legacy/plugins/canvas/tasks/mocks/downloadWorkpad.js diff --git a/x-pack/legacy/plugins/canvas/.storybook/webpack.config.js b/x-pack/legacy/plugins/canvas/.storybook/webpack.config.js index 85cb6d45c595d..cc74faeac6a96 100644 --- a/x-pack/legacy/plugins/canvas/.storybook/webpack.config.js +++ b/x-pack/legacy/plugins/canvas/.storybook/webpack.config.js @@ -6,6 +6,7 @@ const path = require('path'); const webpack = require('webpack'); +const { stringifyRequest } = require('loader-utils'); const CopyWebpackPlugin = require('copy-webpack-plugin'); const { DLL_OUTPUT, KIBANA_ROOT } = require('./constants'); @@ -73,7 +74,20 @@ module.exports = async ({ config }) => { path: path.resolve(KIBANA_ROOT, 'src/optimize/postcss.config.js'), }, }, - { loader: 'sass-loader' }, + { + loader: 'sass-loader', + options: { + prependData(loaderContext) { + return `@import ${stringifyRequest( + loaderContext, + path.resolve(KIBANA_ROOT, 'src/legacy/ui/public/styles/_styling_constants.scss') + )};\n`; + }, + sassOptions: { + includePaths: [path.resolve(KIBANA_ROOT, 'node_modules')], + }, + }, + }, ], }); @@ -86,8 +100,9 @@ module.exports = async ({ config }) => { loader: 'css-loader', options: { importLoaders: 2, - modules: true, - localIdentName: '[name]__[local]___[hash:base64:5]', + modules: { + localIdentName: '[name]__[local]___[hash:base64:5]', + }, }, }, { @@ -159,7 +174,11 @@ module.exports = async ({ config }) => { // what require() calls it will execute within the bundle JSON.stringify({ type, modules: extensions[type] || [] }), ].join(''); - }) + }), + + // Mock out libs used by a few componets to avoid loading in kibana_legacy and platform + new webpack.NormalModuleReplacementPlugin(/lib\/notify/, path.resolve(__dirname, '../tasks/mocks/uiNotify')), + new webpack.NormalModuleReplacementPlugin(/lib\/download_workpad/, path.resolve(__dirname, '../tasks/mocks/downloadWorkpad')), ); // Tell Webpack about relevant extensions diff --git a/x-pack/legacy/plugins/canvas/tasks/mocks/downloadWorkpad.js b/x-pack/legacy/plugins/canvas/tasks/mocks/downloadWorkpad.js new file mode 100644 index 0000000000000..3571448c11aa9 --- /dev/null +++ b/x-pack/legacy/plugins/canvas/tasks/mocks/downloadWorkpad.js @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +export const downloadWorkpad = async workpadId => console.log(`Download workpad ${workpadId}`); + +export const downloadRenderedWorkpad = async renderedWorkpad => + console.log(`Download workpad ${renderedWorkpad.id}`); + +export const downloadRuntime = async basePath => console.log(`Download run time at ${basePath}`); + +export const downloadZippedRuntime = async data => console.log(`Downloading data ${data}`); From 1af82c709fe403cb6a3dccda5e29b0d4589a433f Mon Sep 17 00:00:00 2001 From: eyalkoren <41850454+eyalkoren@users.noreply.github.com> Date: Wed, 8 Apr 2020 17:34:04 +0300 Subject: [PATCH 09/40] [APM] Agent remote configuration: general settings descriptions (#62276) * Updates general remote config descriptions I removed `log_level` from here because it seems it doesn't fit at least the Java, Go and Node agents - see #61821, and it is already deactivated for most others (this doesn't have to be included in this PR though). * Update general_settings.ts * Restore log_level definition * Remove extra spaces Co-authored-by: Nathan L Smith --- .../setting_definitions/general_settings.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/apm/common/agent_configuration/setting_definitions/general_settings.ts b/x-pack/plugins/apm/common/agent_configuration/setting_definitions/general_settings.ts index f1d11c5c70c2b..e73aed35e87f9 100644 --- a/x-pack/plugins/apm/common/agent_configuration/setting_definitions/general_settings.ts +++ b/x-pack/plugins/apm/common/agent_configuration/setting_definitions/general_settings.ts @@ -63,7 +63,7 @@ export const generalSettings: RawSettingDefinition[] = [ 'xpack.apm.agentConfig.captureBody.description', { defaultMessage: - 'For transactions that are HTTP requests, the agent can optionally capture the request body (e.g. POST variables).' + 'For transactions that are HTTP requests, the agent can optionally capture the request body (e.g. POST variables).\nFor transactions that are initiated by receiving a message from a message broker, the agent can capture the textual message body.' } ), options: [ @@ -87,7 +87,7 @@ export const generalSettings: RawSettingDefinition[] = [ 'xpack.apm.agentConfig.captureHeaders.description', { defaultMessage: - 'If set to `true`, the agent will capture request and response headers, including cookies.\n\nNOTE: Setting this to `false` reduces network bandwidth, disk space and object allocations.' + 'If set to `true`, the agent will capture HTTP request and response headers (including cookies), as well as message headers/properties when using messaging frameworks (like Kafka).\n\nNOTE: Setting this to `false` reduces network bandwidth, disk space and object allocations.' } ), excludeAgents: ['js-base', 'rum-js', 'nodejs'] @@ -117,7 +117,7 @@ export const generalSettings: RawSettingDefinition[] = [ }), description: i18n.translate('xpack.apm.agentConfig.recording.description', { defaultMessage: - 'When recording, the agent instruments incoming HTTP requests, tracks errors, and collects and sends metrics. When inactive, the agent works as a noop, not collecting data and not communicating with the APM Server except for polling for updated configuration. As this is a reversible switch, agent threads are not being killed when inactivated, but they will be mostly idle in this state, so the overhead should be negligible. You can use this setting to dynamically control whether Elastic APM is enabled or disabled.' + 'When recording, the agent instruments incoming HTTP requests, tracks errors, and collects and sends metrics. When set to non-recording, the agent works as a noop, not collecting data and not communicating with the APM Server except for polling for updated configuration. As this is a reversible switch, agent threads are not being killed when set to non-recording, but they will be mostly idle in this state, so the overhead should be negligible. You can use this setting to dynamically control whether Elastic APM is enabled or disabled.' }), excludeAgents: ['nodejs'] }, @@ -215,7 +215,7 @@ export const generalSettings: RawSettingDefinition[] = [ 'xpack.apm.agentConfig.transactionSampleRate.description', { defaultMessage: - 'By default, the agent will sample every transaction (e.g. request to your service). To reduce overhead and storage requirements, you can set the sample rate to a value between 0.0 and 1.0. We still record overall time and the result for unsampled transactions, but no context information, labels, or spans.' + 'By default, the agent will sample every transaction (e.g. request to your service). To reduce overhead and storage requirements, you can set the sample rate to a value between 0.0 and 1.0. We still record overall time and the result for unsampled transactions, but not context information, labels, or spans.' } ) } From 5d34697ea57f444ffa7ba5b1ff2e00f1e85ee0e1 Mon Sep 17 00:00:00 2001 From: Yara Tercero Date: Wed, 8 Apr 2020 10:46:06 -0400 Subject: [PATCH 10/40] [SIEM][Detection Engine] - Update list values in REST interfaces (#62320) Summary - #60022 - Follow up on #60171 - Modifies boolean filters to enum of "included" and "excluded" - Adds operator types of enum "match", "match_all", "list", and "exists" - Adds values properties to include those for "list" - DOES NOT FILTER ON THE VALUES JUST YET (That will be a follow on PR) --- .../routes/__mocks__/request_responses.ts | 28 ++-- .../routes/__mocks__/utils.ts | 28 ++-- .../routes/rules/validate.test.ts | 28 ++-- .../add_prepackaged_rules_schema.test.ts | 28 ++-- .../schemas/create_rules_schema.test.ts | 28 ++-- .../schemas/import_rules_schema.test.ts | 28 ++-- .../routes/schemas/patch_rules_schema.test.ts | 53 ++++--- .../schemas/response/__mocks__/utils.ts | 28 ++-- .../routes/schemas/response/schemas.ts | 37 +++-- .../routes/schemas/schemas.ts | 30 +++- .../schemas/types/lists_default_array.test.ts | 131 ++++++++++++++++-- .../schemas/types/lists_default_array.ts | 8 +- .../schemas/update_rules_schema.test.ts | 25 ++-- .../rules/get_export_all.test.ts | 28 ++-- .../rules/get_export_by_object_ids.test.ts | 56 +++++--- .../scripts/rules/patches/update_list.json | 27 ++-- .../rules/queries/query_with_list.json | 32 +++-- .../scripts/rules/updates/update_list.json | 27 ++-- .../signals/__mocks__/es_results.ts | 28 ++-- .../signals/build_bulk_body.test.ts | 112 +++++++++------ .../signals/build_rule.test.ts | 84 ++++++----- 21 files changed, 578 insertions(+), 296 deletions(-) diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/__mocks__/request_responses.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/__mocks__/request_responses.ts index 3b24b722f7356..77c1641d073c6 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/__mocks__/request_responses.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/__mocks__/request_responses.ts @@ -450,25 +450,31 @@ export const getResult = (): RuleAlertType => ({ lists: [ { field: 'source.ip', - boolean_operator: 'and', - values: [ - { - name: '127.0.0.1', - type: 'value', - }, - ], + values_operator: 'included', + values_type: 'exists', }, { field: 'host.name', - boolean_operator: 'and not', + values_operator: 'excluded', + values_type: 'match', values: [ { name: 'rock01', - type: 'value', }, + ], + and: [ { - name: 'mothra', - type: 'value', + field: 'host.id', + values_operator: 'included', + values_type: 'match_all', + values: [ + { + name: '123', + }, + { + name: '678', + }, + ], }, ], }, diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/__mocks__/utils.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/__mocks__/utils.ts index 63fe51f2c81cd..c929b0718207d 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/__mocks__/utils.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/__mocks__/utils.ts @@ -141,25 +141,31 @@ export const getOutputRuleAlertForRest = (): Omit< lists: [ { field: 'source.ip', - boolean_operator: 'and', - values: [ - { - name: '127.0.0.1', - type: 'value', - }, - ], + values_operator: 'included', + values_type: 'exists', }, { field: 'host.name', - boolean_operator: 'and not', + values_operator: 'excluded', + values_type: 'match', values: [ { name: 'rock01', - type: 'value', }, + ], + and: [ { - name: 'mothra', - type: 'value', + field: 'host.id', + values_operator: 'included', + values_type: 'match_all', + values: [ + { + name: '123', + }, + { + name: '678', + }, + ], }, ], }, diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/validate.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/validate.test.ts index 77e05796fbcbe..7537401e5a366 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/validate.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/validate.test.ts @@ -74,25 +74,31 @@ export const ruleOutput: RulesSchema = { lists: [ { field: 'source.ip', - boolean_operator: 'and', - values: [ - { - name: '127.0.0.1', - type: 'value', - }, - ], + values_operator: 'included', + values_type: 'exists', }, { field: 'host.name', - boolean_operator: 'and not', + values_operator: 'excluded', + values_type: 'match', values: [ { name: 'rock01', - type: 'value', }, + ], + and: [ { - name: 'mothra', - type: 'value', + field: 'host.id', + values_operator: 'included', + values_type: 'match_all', + values: [ + { + name: '123', + }, + { + name: '678', + }, + ], }, ], }, diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/add_prepackaged_rules_schema.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/add_prepackaged_rules_schema.test.ts index b10627d151fa2..8c741c937bf15 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/add_prepackaged_rules_schema.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/add_prepackaged_rules_schema.test.ts @@ -1561,25 +1561,31 @@ describe('add prepackaged rules schema', () => { lists: [ { field: 'source.ip', - boolean_operator: 'and', - values: [ - { - name: '127.0.0.1', - type: 'value', - }, - ], + values_operator: 'included', + values_type: 'exists', }, { field: 'host.name', - boolean_operator: 'and not', + values_operator: 'excluded', + values_type: 'match', values: [ { name: 'rock01', - type: 'value', }, + ], + and: [ { - name: 'mothra', - type: 'value', + field: 'host.id', + values_operator: 'included', + values_type: 'match_all', + values: [ + { + name: '123', + }, + { + name: '678', + }, + ], }, ], }, diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/create_rules_schema.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/create_rules_schema.test.ts index 08bd01ee9a1a0..e56e8e5fe34d3 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/create_rules_schema.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/create_rules_schema.test.ts @@ -1526,25 +1526,31 @@ describe('create rules schema', () => { lists: [ { field: 'source.ip', - boolean_operator: 'and', - values: [ - { - name: '127.0.0.1', - type: 'value', - }, - ], + values_operator: 'included', + values_type: 'exists', }, { field: 'host.name', - boolean_operator: 'and not', + values_operator: 'excluded', + values_type: 'match', values: [ { name: 'rock01', - type: 'value', }, + ], + and: [ { - name: 'mothra', - type: 'value', + field: 'host.id', + values_operator: 'included', + values_type: 'match_all', + values: [ + { + name: '123', + }, + { + name: '678', + }, + ], }, ], }, diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/import_rules_schema.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/import_rules_schema.test.ts index c8e5bb981f921..40f7b19ea12b3 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/import_rules_schema.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/import_rules_schema.test.ts @@ -1747,25 +1747,31 @@ describe('import rules schema', () => { lists: [ { field: 'source.ip', - boolean_operator: 'and', - values: [ - { - name: '127.0.0.1', - type: 'value', - }, - ], + values_operator: 'included', + values_type: 'exists', }, { field: 'host.name', - boolean_operator: 'and not', + values_operator: 'excluded', + values_type: 'match', values: [ { name: 'rock01', - type: 'value', }, + ], + and: [ { - name: 'mothra', - type: 'value', + field: 'host.id', + values_operator: 'included', + values_type: 'match_all', + values: [ + { + name: '123', + }, + { + name: '678', + }, + ], }, ], }, diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/patch_rules_schema.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/patch_rules_schema.test.ts index 45b5028f392b9..e01a8f40fcea4 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/patch_rules_schema.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/patch_rules_schema.test.ts @@ -1229,25 +1229,31 @@ describe('patch rules schema', () => { lists: [ { field: 'source.ip', - boolean_operator: 'and', - values: [ - { - name: '127.0.0.1', - type: 'value', - }, - ], + values_operator: 'included', + values_type: 'exists', }, { field: 'host.name', - boolean_operator: 'and not', + values_operator: 'excluded', + values_type: 'match', values: [ { name: 'rock01', - type: 'value', }, + ], + and: [ { - name: 'mothra', - type: 'value', + field: 'host.id', + values_operator: 'included', + values_type: 'match_all', + values: [ + { + name: '123', + }, + { + name: '678', + }, + ], }, ], }, @@ -1263,25 +1269,28 @@ describe('patch rules schema', () => { lists: [ { field: 'source.ip', - boolean_operator: 'and', - values: [ - { - name: '127.0.0.1', - type: 'value', - }, - ], + values_operator: 'included', + values_type: 'exists', }, { field: 'host.name', - boolean_operator: 'and not', + values_operator: 'excluded', + values_type: 'match', values: [ { name: 'rock01', - type: 'value', }, + ], + and: [ { - name: 'mothra', - type: 'value', + field: 'host.id', + values_operator: 'included', + values_type: 'match_all', + values: [ + { + name: '123', + }, + ], }, ], }, diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/response/__mocks__/utils.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/response/__mocks__/utils.ts index 46cd1b653b5b4..d5ea950d163f5 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/response/__mocks__/utils.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/response/__mocks__/utils.ts @@ -66,25 +66,31 @@ export const getBaseResponsePayload = (anchorDate: string = ANCHOR_DATE): RulesS lists: [ { field: 'source.ip', - boolean_operator: 'and', - values: [ - { - name: '127.0.0.1', - type: 'value', - }, - ], + values_operator: 'included', + values_type: 'exists', }, { field: 'host.name', - boolean_operator: 'and not', + values_operator: 'excluded', + values_type: 'match', values: [ { name: 'rock01', - type: 'value', }, + ], + and: [ { - name: 'mothra', - type: 'value', + field: 'host.id', + values_operator: 'included', + values_type: 'match_all', + values: [ + { + name: '123', + }, + { + name: '678', + }, + ], }, ], }, diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/response/schemas.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/response/schemas.ts index 538c8f754fd6e..faae1dde83545 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/response/schemas.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/response/schemas.ts @@ -154,13 +154,34 @@ export const note = t.string; // NOTE: Experimental list support not being shipped currently and behind a feature flag // TODO: Remove this comment once we lists have passed testing and is ready for the release -export const boolean_operator = t.keyof({ and: null, 'and not': null }); -export const list_type = t.keyof({ value: null }); // TODO: (LIST-FEATURE) Eventually this can include "list" when we support lists CRUD -export const list_value = t.exact(t.type({ name: t.string, type: list_type })); +export const list_field = t.string; +export const list_values_operator = t.keyof({ included: null, excluded: null }); +export const list_values_type = t.keyof({ match: null, match_all: null, list: null, exists: null }); +export const list_values = t.exact( + t.intersection([ + t.type({ + name: t.string, + }), + t.partial({ + id: t.string, + description: t.string, + created_at, + }), + ]) +); export const list = t.exact( - t.type({ - field: t.string, - boolean_operator, - values: t.array(list_value), - }) + t.intersection([ + t.type({ + field: t.string, + values_operator: list_values_operator, + values_type: list_values_type, + }), + t.partial({ values: t.array(list_values) }), + ]) ); +export const list_and = t.intersection([ + list, + t.partial({ + and: t.array(list), + }), +]); diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/schemas.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/schemas.ts index 16e419f389f09..c17ae8466a86c 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/schemas.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/schemas.ts @@ -126,12 +126,28 @@ export const note = Joi.string(); // NOTE: Experimental list support not being shipped currently and behind a feature flag // TODO: (LIST-FEATURE) Remove this comment once we lists have passed testing and is ready for the release -export const boolean_operator = Joi.string().valid('and', 'and not'); -export const list_type = Joi.string().valid('value'); // TODO: (LIST-FEATURE) Eventually this can be "list" when we support list types -export const list_value = Joi.object({ name: Joi.string().required(), type: list_type.required() }); +export const list_field = Joi.string(); +export const list_values_operator = Joi.string().valid(['included', 'excluded']); +export const list_values_types = Joi.string().valid(['match', 'match_all', 'list', 'exists']); +export const list_values = Joi.object({ + name: Joi.string().required(), + id: Joi.string(), + description: Joi.string(), + created_at, +}); export const list = Joi.object({ - field: Joi.string().required(), - boolean_operator: boolean_operator.required(), - values: Joi.array().items(list_value), + field: list_field.required(), + values_operator: list_values_operator.required(), + values_type: list_values_types.required(), + values: Joi.when('values_type', { + is: 'exists', + then: Joi.forbidden(), + otherwise: Joi.array() + .items(list_values) + .required(), + }), +}); +export const list_and = Joi.object({ + and: Joi.array().items(list), }); -export const lists = Joi.array().items(list); +export const lists = Joi.array().items(list.concat(list_and)); diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/types/lists_default_array.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/types/lists_default_array.test.ts index 14df1c3d8cd55..e8a9c7b0886a1 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/types/lists_default_array.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/types/lists_default_array.test.ts @@ -23,25 +23,79 @@ describe('lists_default_array', () => { const payload = [ { field: 'source.ip', - boolean_operator: 'and', + values_operator: 'included', + values_type: 'exists', + }, + { + field: 'host.name', + values_operator: 'excluded', + values_type: 'match', values: [ { - name: '127.0.0.1', - type: 'value', + name: 'rock01', + }, + ], + and: [ + { + field: 'host.id', + values_operator: 'included', + values_type: 'match_all', + values: [ + { + name: '123', + }, + { + name: '678', + }, + ], }, ], }, + ]; + const decoded = ListsDefaultArray.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should not validate an array of lists that includes a values_operator other than included or excluded', () => { + const payload = [ + { + field: 'source.ip', + values_operator: 'included', + values_type: 'exists', + }, + { + field: 'host.name', + values_operator: 'excluded', + values_type: 'exists', + }, + { + field: 'host.hostname', + values_operator: 'jibber jabber', + values_type: 'exists', + }, + ]; + const decoded = ListsDefaultArray.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "jibber jabber" supplied to "values_operator"', + ]); + expect(message.schema).toEqual({}); + }); + + // TODO - this scenario should never come up, as the values key is forbidden when values_type is "exists" in the incoming schema - need to find a good way to do this in io-ts + test('it will validate an array of lists that includes "values" when "values_type" is "exists"', () => { + const payload = [ { field: 'host.name', - boolean_operator: 'and not', + values_operator: 'excluded', + values_type: 'exists', values: [ { - name: 'rock01', - type: 'value', - }, - { - name: 'mothra', - type: 'value', + name: '127.0.0.1', }, ], }, @@ -53,15 +107,63 @@ describe('lists_default_array', () => { expect(message.schema).toEqual(payload); }); + // TODO - this scenario should never come up, as the values key is required when values_type is "match" in the incoming schema - need to find a good way to do this in io-ts + test('it will validate an array of lists that does not include "values" when "values_type" is "match"', () => { + const payload = [ + { + field: 'host.name', + values_operator: 'excluded', + values_type: 'match', + }, + ]; + const decoded = ListsDefaultArray.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + // TODO - this scenario should never come up, as the values key is required when values_type is "match_all" in the incoming schema - need to find a good way to do this in io-ts + test('it will validate an array of lists that does not include "values" when "values_type" is "match_all"', () => { + const payload = [ + { + field: 'host.name', + values_operator: 'excluded', + values_type: 'match_all', + }, + ]; + const decoded = ListsDefaultArray.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + // TODO - this scenario should never come up, as the values key is required when values_type is "list" in the incoming schema - need to find a good way to do this in io-ts + test('it should not validate an array of lists that does not include "values" when "values_type" is "list"', () => { + const payload = [ + { + field: 'host.name', + values_operator: 'excluded', + values_type: 'list', + }, + ]; + const decoded = ListsDefaultArray.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + test('it should not validate an array with a number', () => { const payload = [ { field: 'source.ip', - boolean_operator: 'and', + values_operator: 'included', + values_type: 'exists', values: [ { name: '127.0.0.1', - type: 'value', }, ], }, @@ -70,7 +172,10 @@ describe('lists_default_array', () => { const decoded = ListsDefaultArray.decode(payload); const message = pipe(decoded, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "5" supplied to ""', + 'Invalid value "5" supplied to ""', + ]); expect(message.schema).toEqual({}); }); diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/types/lists_default_array.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/types/lists_default_array.ts index 0e0944a11b416..85a38e296494a 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/types/lists_default_array.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/types/lists_default_array.ts @@ -7,10 +7,10 @@ import * as t from 'io-ts'; import { Either } from 'fp-ts/lib/Either'; -import { list } from '../response/schemas'; +import { list_and as listAnd } from '../response/schemas'; export type ListsDefaultArrayC = t.Type; -type List = t.TypeOf; +type List = t.TypeOf; /** * Types the ListsDefaultArray as: @@ -18,9 +18,9 @@ type List = t.TypeOf; */ export const ListsDefaultArray: ListsDefaultArrayC = new t.Type( 'listsWithDefaultArray', - t.array(list).is, + t.array(listAnd).is, (input): Either => - input == null ? t.success([]) : t.array(list).decode(input), + input == null ? t.success([]) : t.array(listAnd).decode(input), t.identity ); diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/update_rules_schema.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/update_rules_schema.test.ts index 6f6beea7fa5fb..e8f9aad620ca0 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/update_rules_schema.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas/update_rules_schema.test.ts @@ -1552,25 +1552,28 @@ describe('create rules schema', () => { lists: [ { field: 'source.ip', - boolean_operator: 'and', - values: [ - { - name: '127.0.0.1', - type: 'value', - }, - ], + values_operator: 'included', + values_type: 'exists', }, { field: 'host.name', - boolean_operator: 'and not', + values_operator: 'excluded', + values_type: 'match', values: [ { name: 'rock01', - type: 'value', }, + ], + and: [ { - name: 'mothra', - type: 'value', + field: 'host.id', + values_operator: 'included', + values_type: 'match_all', + values: [ + { + name: '123', + }, + ], }, ], }, diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/get_export_all.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/get_export_all.test.ts index ca6fb15e1fad9..dd004e3685b1d 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/get_export_all.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/get_export_all.test.ts @@ -82,25 +82,31 @@ describe('getExportAll', () => { lists: [ { field: 'source.ip', - boolean_operator: 'and', - values: [ - { - name: '127.0.0.1', - type: 'value', - }, - ], + values_operator: 'included', + values_type: 'exists', }, { field: 'host.name', - boolean_operator: 'and not', + values_operator: 'excluded', + values_type: 'match', values: [ { name: 'rock01', - type: 'value', }, + ], + and: [ { - name: 'mothra', - type: 'value', + field: 'host.id', + values_operator: 'included', + values_type: 'match_all', + values: [ + { + name: '123', + }, + { + name: '678', + }, + ], }, ], }, diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/get_export_by_object_ids.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/get_export_by_object_ids.test.ts index 175c906f7996c..715cb23e8444a 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/get_export_by_object_ids.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/get_export_by_object_ids.test.ts @@ -90,25 +90,31 @@ describe('get_export_by_object_ids', () => { lists: [ { field: 'source.ip', - boolean_operator: 'and', - values: [ - { - name: '127.0.0.1', - type: 'value', - }, - ], + values_operator: 'included', + values_type: 'exists', }, { field: 'host.name', - boolean_operator: 'and not', + values_operator: 'excluded', + values_type: 'match', values: [ { name: 'rock01', - type: 'value', }, + ], + and: [ { - name: 'mothra', - type: 'value', + field: 'host.id', + values_operator: 'included', + values_type: 'match_all', + values: [ + { + name: '123', + }, + { + name: '678', + }, + ], }, ], }, @@ -212,25 +218,31 @@ describe('get_export_by_object_ids', () => { lists: [ { field: 'source.ip', - boolean_operator: 'and', - values: [ - { - name: '127.0.0.1', - type: 'value', - }, - ], + values_operator: 'included', + values_type: 'exists', }, { field: 'host.name', - boolean_operator: 'and not', + values_operator: 'excluded', + values_type: 'match', values: [ { name: 'rock01', - type: 'value', }, + ], + and: [ { - name: 'mothra', - type: 'value', + field: 'host.id', + values_operator: 'included', + values_type: 'match_all', + values: [ + { + name: '123', + }, + { + name: '678', + }, + ], }, ], }, diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/scripts/rules/patches/update_list.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/scripts/rules/patches/update_list.json index 8c86f4c85af1d..4db8724db4e13 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/scripts/rules/patches/update_list.json +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/scripts/rules/patches/update_list.json @@ -3,21 +3,28 @@ "lists": [ { "field": "source.ip", - "boolean_operator": "and", - "values": [ - { - "name": "127.0.0.1", - "type": "value" - } - ] + "values_operator": "excluded", + "values_type": "exists" }, { "field": "host.name", - "boolean_operator": "and not", + "values_operator": "included", + "values_type": "match", "values": [ { - "name": "rock01", - "type": "value" + "name": "rock01" + } + ], + "and": [ + { + "field": "host.id", + "values_operator": "included", + "values_type": "match_all", + "values": [ + { + "name": "123456" + } + ] } ] } diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/scripts/rules/queries/query_with_list.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/scripts/rules/queries/query_with_list.json index f6856eec59966..997d03369a699 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/scripts/rules/queries/query_with_list.json +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/scripts/rules/queries/query_with_list.json @@ -9,25 +9,31 @@ "lists": [ { "field": "source.ip", - "boolean_operator": "and", - "values": [ - { - "name": "127.0.0.1", - "type": "value" - } - ] + "values_operator": "included", + "values_type": "exists" }, { "field": "host.name", - "boolean_operator": "and not", + "values_operator": "excluded", + "values_type": "match", "values": [ { - "name": "rock01", - "type": "value" - }, + "name": "rock01" + } + ], + "and": [ { - "name": "mothra", - "type": "value" + "field": "host.id", + "values_operator": "included", + "values_type": "match_all", + "values": [ + { + "name": "123" + }, + { + "name": "678" + } + ] } ] } diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/scripts/rules/updates/update_list.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/scripts/rules/updates/update_list.json index 6704c9676fa56..66b198974f574 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/scripts/rules/updates/update_list.json +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/scripts/rules/updates/update_list.json @@ -9,21 +9,28 @@ "lists": [ { "field": "source.ip", - "boolean_operator": "and", - "values": [ - { - "name": "127.0.0.1", - "type": "value" - } - ] + "values_operator": "excluded", + "values_type": "exists" }, { "field": "host.name", - "boolean_operator": "and not", + "values_operator": "included", + "values_type": "match", "values": [ { - "name": "rock01", - "type": "value" + "name": "rock01" + } + ], + "and": [ + { + "field": "host.id", + "values_operator": "included", + "values_type": "match_all", + "values": [ + { + "name": "123456" + } + ] } ] } diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/__mocks__/es_results.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/__mocks__/es_results.ts index 6d7d7e93d7e6e..7a211c5631da6 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/__mocks__/es_results.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/__mocks__/es_results.ts @@ -47,25 +47,31 @@ export const sampleRuleAlertParams = ( lists: [ { field: 'source.ip', - boolean_operator: 'and', - values: [ - { - name: '127.0.0.1', - type: 'value', - }, - ], + values_operator: 'included', + values_type: 'exists', }, { field: 'host.name', - boolean_operator: 'and not', + values_operator: 'excluded', + values_type: 'match', values: [ { name: 'rock01', - type: 'value', }, + ], + and: [ { - name: 'mothra', - type: 'value', + field: 'host.id', + values_operator: 'included', + values_type: 'match_all', + values: [ + { + name: '123', + }, + { + name: '678', + }, + ], }, ], }, diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/build_bulk_body.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/build_bulk_body.test.ts index f2c2b99bdac8c..f1729e35ce1f0 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/build_bulk_body.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/build_bulk_body.test.ts @@ -93,25 +93,31 @@ describe('buildBulkBody', () => { lists: [ { field: 'source.ip', - boolean_operator: 'and', - values: [ - { - name: '127.0.0.1', - type: 'value', - }, - ], + values_operator: 'included', + values_type: 'exists', }, { field: 'host.name', - boolean_operator: 'and not', + values_operator: 'excluded', + values_type: 'match', values: [ { name: 'rock01', - type: 'value', }, + ], + and: [ { - name: 'mothra', - type: 'value', + field: 'host.id', + values_operator: 'included', + values_type: 'match_all', + values: [ + { + name: '123', + }, + { + name: '678', + }, + ], }, ], }, @@ -213,25 +219,31 @@ describe('buildBulkBody', () => { lists: [ { field: 'source.ip', - boolean_operator: 'and', - values: [ - { - name: '127.0.0.1', - type: 'value', - }, - ], + values_operator: 'included', + values_type: 'exists', }, { field: 'host.name', - boolean_operator: 'and not', + values_operator: 'excluded', + values_type: 'match', values: [ { name: 'rock01', - type: 'value', }, + ], + and: [ { - name: 'mothra', - type: 'value', + field: 'host.id', + values_operator: 'included', + values_type: 'match_all', + values: [ + { + name: '123', + }, + { + name: '678', + }, + ], }, ], }, @@ -331,25 +343,31 @@ describe('buildBulkBody', () => { lists: [ { field: 'source.ip', - boolean_operator: 'and', - values: [ - { - name: '127.0.0.1', - type: 'value', - }, - ], + values_operator: 'included', + values_type: 'exists', }, { field: 'host.name', - boolean_operator: 'and not', + values_operator: 'excluded', + values_type: 'match', values: [ { name: 'rock01', - type: 'value', }, + ], + and: [ { - name: 'mothra', - type: 'value', + field: 'host.id', + values_operator: 'included', + values_type: 'match_all', + values: [ + { + name: '123', + }, + { + name: '678', + }, + ], }, ], }, @@ -442,25 +460,31 @@ describe('buildBulkBody', () => { lists: [ { field: 'source.ip', - boolean_operator: 'and', - values: [ - { - name: '127.0.0.1', - type: 'value', - }, - ], + values_operator: 'included', + values_type: 'exists', }, { field: 'host.name', - boolean_operator: 'and not', + values_operator: 'excluded', + values_type: 'match', values: [ { name: 'rock01', - type: 'value', }, + ], + and: [ { - name: 'mothra', - type: 'value', + field: 'host.id', + values_operator: 'included', + values_type: 'match_all', + values: [ + { + name: '123', + }, + { + name: '678', + }, + ], }, ], }, diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/build_rule.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/build_rule.test.ts index e360ceaf02f4d..e5183ed4df7bd 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/build_rule.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/build_rule.test.ts @@ -82,25 +82,31 @@ describe('buildRule', () => { lists: [ { field: 'source.ip', - boolean_operator: 'and', - values: [ - { - name: '127.0.0.1', - type: 'value', - }, - ], + values_operator: 'included', + values_type: 'exists', }, { field: 'host.name', - boolean_operator: 'and not', + values_operator: 'excluded', + values_type: 'match', values: [ { name: 'rock01', - type: 'value', }, + ], + and: [ { - name: 'mothra', - type: 'value', + field: 'host.id', + values_operator: 'included', + values_type: 'match_all', + values: [ + { + name: '123', + }, + { + name: '678', + }, + ], }, ], }, @@ -159,25 +165,31 @@ describe('buildRule', () => { lists: [ { field: 'source.ip', - boolean_operator: 'and', - values: [ - { - name: '127.0.0.1', - type: 'value', - }, - ], + values_operator: 'included', + values_type: 'exists', }, { field: 'host.name', - boolean_operator: 'and not', + values_operator: 'excluded', + values_type: 'match', values: [ { name: 'rock01', - type: 'value', }, + ], + and: [ { - name: 'mothra', - type: 'value', + field: 'host.id', + values_operator: 'included', + values_type: 'match_all', + values: [ + { + name: '123', + }, + { + name: '678', + }, + ], }, ], }, @@ -235,25 +247,31 @@ describe('buildRule', () => { lists: [ { field: 'source.ip', - boolean_operator: 'and', - values: [ - { - name: '127.0.0.1', - type: 'value', - }, - ], + values_operator: 'included', + values_type: 'exists', }, { field: 'host.name', - boolean_operator: 'and not', + values_operator: 'excluded', + values_type: 'match', values: [ { name: 'rock01', - type: 'value', }, + ], + and: [ { - name: 'mothra', - type: 'value', + field: 'host.id', + values_operator: 'included', + values_type: 'match_all', + values: [ + { + name: '123', + }, + { + name: '678', + }, + ], }, ], }, From 90e6f2ca6de48858e9faa8a802905abf3aa23e8f Mon Sep 17 00:00:00 2001 From: Peter Pisljar Date: Wed, 8 Apr 2020 16:57:23 +0200 Subject: [PATCH 11/40] fixing multiple metrics (#62929) --- .../options/metrics_axes/__snapshots__/index.test.tsx.snap | 3 +++ .../public/components/options/metrics_axes/index.test.tsx | 1 + .../public/components/options/metrics_axes/index.tsx | 2 +- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/__snapshots__/index.test.tsx.snap b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/__snapshots__/index.test.tsx.snap index 442bc826d51fc..09e0753d592e5 100644 --- a/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/__snapshots__/index.test.tsx.snap +++ b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/__snapshots__/index.test.tsx.snap @@ -54,6 +54,7 @@ exports[`MetricsAxisOptions component should init with the default set of props } vis={ Object { + "serialize": [MockFunction], "setState": [MockFunction], "type": Object { "schemas": Object { @@ -126,6 +127,7 @@ exports[`MetricsAxisOptions component should init with the default set of props } vis={ Object { + "serialize": [MockFunction], "setState": [MockFunction], "type": Object { "schemas": Object { @@ -169,6 +171,7 @@ exports[`MetricsAxisOptions component should init with the default set of props setCategoryAxis={[Function]} vis={ Object { + "serialize": [MockFunction], "setState": [MockFunction], "type": Object { "schemas": Object { diff --git a/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/index.test.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/index.test.tsx index a3f150e718817..524792d1460fe 100644 --- a/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/index.test.tsx +++ b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/index.test.tsx @@ -95,6 +95,7 @@ describe('MetricsAxisOptions component', () => { schemas: { metrics: [{ name: 'metric' }] }, }, setState: jest.fn(), + serialize: jest.fn(), }, stateParams: { valueAxes: [axis], diff --git a/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/index.tsx b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/index.tsx index c7b4562b1087e..114305d653dd1 100644 --- a/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/index.tsx +++ b/src/legacy/core_plugins/vis_type_vislib/public/components/options/metrics_axes/index.tsx @@ -299,7 +299,7 @@ function MetricsAxisOptions(props: ValidationVisOptionsProps) }, [stateParams.seriesParams]); useEffect(() => { - vis.setState({ type: visType } as any); + vis.setState({ ...vis.serialize(), type: visType }); }, [vis, visType]); return isTabSelected ? ( From 202366310483f51f614b3b1f2001917547803e2b Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Wed, 8 Apr 2020 10:03:37 -0600 Subject: [PATCH 12/40] [Maps] Add date-fields to metrics selection (#62629) Co-authored-by: Elastic Machine --- x-pack/plugins/maps/public/components/metric_editor.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/maps/public/components/metric_editor.js b/x-pack/plugins/maps/public/components/metric_editor.js index 530f402592b2b..d1affe2f42190 100644 --- a/x-pack/plugins/maps/public/components/metric_editor.js +++ b/x-pack/plugins/maps/public/components/metric_editor.js @@ -24,8 +24,13 @@ function filterFieldsForAgg(fields, aggType) { return getTermsFields(fields); } + const metricAggFieldTypes = ['number']; + if (aggType !== AGG_TYPE.SUM) { + metricAggFieldTypes.push('date'); + } + return fields.filter(field => { - return field.aggregatable && field.type === 'number'; + return field.aggregatable && metricAggFieldTypes.includes(field.type); }); } From 3457dde6f55c606a3f693ef75fe237ab07b56904 Mon Sep 17 00:00:00 2001 From: nnamdifrankie <56440728+nnamdifrankie@users.noreply.github.com> Date: Wed, 8 Apr 2020 12:10:00 -0400 Subject: [PATCH 13/40] [Endpoint] EMT-146: add host status info to the metadata API response (#62876) [Endpoint] EMT-146: add host status info to the metadata API response --- x-pack/plugins/endpoint/common/types.ts | 28 ++++++++++++++++++- .../endpoint/store/hosts/action.ts | 4 +-- .../endpoint/store/hosts/index.test.ts | 2 +- .../endpoint/store/hosts/middleware.test.ts | 2 +- .../store/hosts/mock_host_result_list.ts | 7 +++-- .../endpoint/store/hosts/reducer.ts | 4 +-- .../server/routes/alerts/details/handlers.ts | 2 +- .../endpoint/server/routes/metadata/index.ts | 15 +++++++--- .../server/routes/metadata/metadata.test.ts | 9 +++--- .../api_integration/apis/endpoint/metadata.ts | 17 +++++------ 10 files changed, 64 insertions(+), 26 deletions(-) diff --git a/x-pack/plugins/endpoint/common/types.ts b/x-pack/plugins/endpoint/common/types.ts index e8e1281a88925..a614526d92a3f 100644 --- a/x-pack/plugins/endpoint/common/types.ts +++ b/x-pack/plugins/endpoint/common/types.ts @@ -86,7 +86,7 @@ export interface AlertResultList { export interface HostResultList { /* the hosts restricted by the page size */ - hosts: HostMetadata[]; + hosts: HostInfo[]; /* the total number of unique hosts in the index */ total: number; /* the page size requested */ @@ -252,6 +252,32 @@ export type AlertData = AlertEvent & AlertMetadata; export type AlertDetails = AlertData & AlertState; +/** + * The status of the host + */ +export enum HostStatus { + /** + * Default state of the host when no host information is present or host information cannot + * be retrieved. e.g. API error + */ + ERROR = 'error', + + /** + * Host is online as indicated by its checkin status during the last checkin window + */ + ONLINE = 'online', + + /** + * Host is offline as indicated by its checkin status during the last checkin window + */ + OFFLINE = 'offline', +} + +export type HostInfo = Immutable<{ + metadata: HostMetadata; + host_status: HostStatus; +}>; + export type HostMetadata = Immutable<{ '@timestamp': number; event: { diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/action.ts b/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/action.ts index dee35aa3b895a..4dafa68ddb647 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/action.ts +++ b/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/action.ts @@ -5,7 +5,7 @@ */ import { HostListPagination, ServerApiError } from '../../types'; -import { HostResultList, HostMetadata } from '../../../../../common/types'; +import { HostResultList, HostInfo } from '../../../../../common/types'; interface ServerReturnedHostList { type: 'serverReturnedHostList'; @@ -14,7 +14,7 @@ interface ServerReturnedHostList { interface ServerReturnedHostDetails { type: 'serverReturnedHostDetails'; - payload: HostMetadata; + payload: HostInfo; } interface ServerFailedToReturnHostDetails { diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/index.test.ts b/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/index.test.ts index 9aff66cdfb75e..6148934343635 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/index.test.ts +++ b/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/index.test.ts @@ -52,7 +52,7 @@ describe('HostList store concerns', () => { }); const currentState = store.getState(); - expect(currentState.hosts).toEqual(payload.hosts); + expect(currentState.hosts).toEqual(payload.hosts.map(hostInfo => hostInfo.metadata)); expect(currentState.pageSize).toEqual(payload.request_page_size); expect(currentState.pageIndex).toEqual(payload.request_page_index); expect(currentState.total).toEqual(payload.total); diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/middleware.test.ts b/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/middleware.test.ts index a1973a38b6534..8c8578426aa29 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/middleware.test.ts +++ b/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/middleware.test.ts @@ -58,6 +58,6 @@ describe('host list middleware', () => { paging_properties: [{ page_index: 0 }, { page_size: 10 }], }), }); - expect(listData(getState())).toEqual(apiResponse.hosts); + expect(listData(getState())).toEqual(apiResponse.hosts.map(hostInfo => hostInfo.metadata)); }); }); diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/mock_host_result_list.ts b/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/mock_host_result_list.ts index db39ecf448312..d4c2602e34387 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/mock_host_result_list.ts +++ b/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/mock_host_result_list.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { HostResultList } from '../../../../../common/types'; +import { HostResultList, HostStatus } from '../../../../../common/types'; import { EndpointDocGenerator } from '../../../../../common/generate_data'; export const mockHostResultList: (options?: { @@ -27,7 +27,10 @@ export const mockHostResultList: (options?: { const hosts = []; for (let index = 0; index < actualCountToReturn; index++) { const generator = new EndpointDocGenerator('seed'); - hosts.push(generator.generateHostMetadata()); + hosts.push({ + metadata: generator.generateHostMetadata(), + host_status: HostStatus.ERROR, + }); } const mock: HostResultList = { hosts, diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/reducer.ts b/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/reducer.ts index fd70317a9f37e..ad6741dab7be7 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/reducer.ts +++ b/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/reducer.ts @@ -34,7 +34,7 @@ export const hostListReducer: Reducer = ( } = action.payload; return { ...state, - hosts, + hosts: hosts.map(hostInfo => hostInfo.metadata), total, pageSize, pageIndex, @@ -43,7 +43,7 @@ export const hostListReducer: Reducer = ( } else if (action.type === 'serverReturnedHostDetails') { return { ...state, - details: action.payload, + details: action.payload.metadata, }; } else if (action.type === 'serverFailedToReturnHostDetails') { return { diff --git a/x-pack/plugins/endpoint/server/routes/alerts/details/handlers.ts b/x-pack/plugins/endpoint/server/routes/alerts/details/handlers.ts index 725e362f91ec7..0f32deb4fad9b 100644 --- a/x-pack/plugins/endpoint/server/routes/alerts/details/handlers.ts +++ b/x-pack/plugins/endpoint/server/routes/alerts/details/handlers.ts @@ -41,7 +41,7 @@ export const alertDetailsHandlerWrapper = function( id: response._id, ...response._source, state: { - host_metadata: currentHostInfo, + host_metadata: currentHostInfo?.metadata, }, next: await pagination.getNextUrl(), prev: await pagination.getPrevUrl(), diff --git a/x-pack/plugins/endpoint/server/routes/metadata/index.ts b/x-pack/plugins/endpoint/server/routes/metadata/index.ts index ef01db9af98c4..450469914bc50 100644 --- a/x-pack/plugins/endpoint/server/routes/metadata/index.ts +++ b/x-pack/plugins/endpoint/server/routes/metadata/index.ts @@ -8,7 +8,7 @@ import { IRouter, RequestHandlerContext } from 'kibana/server'; import { SearchResponse } from 'elasticsearch'; import { schema } from '@kbn/config-schema'; -import { HostMetadata, HostResultList } from '../../../common/types'; +import { HostInfo, HostMetadata, HostResultList, HostStatus } from '../../../common/types'; import { EndpointAppContext } from '../../types'; import { getESQueryHostMetadataByID, kibanaRequestToMetadataListESQuery } from './query_builders'; @@ -87,7 +87,7 @@ export function registerEndpointRoutes(router: IRouter, endpointAppContext: Endp export async function getHostData( context: RequestHandlerContext, id: string -): Promise { +): Promise { const query = getESQueryHostMetadataByID(id); const response = (await context.core.elasticsearch.dataClient.callAsCurrentUser( 'search', @@ -98,7 +98,7 @@ export async function getHostData( return undefined; } - return response.hits.hits[0]._source; + return enrichHostMetadata(response.hits.hits[0]._source); } function mapToHostResultList( @@ -113,7 +113,7 @@ function mapToHostResultList( hosts: searchResponse.hits.hits .map(response => response.inner_hits.most_recent.hits.hits) .flatMap(data => data as HitSource) - .map(entry => entry._source), + .map(entry => enrichHostMetadata(entry._source)), total: totalNumberOfHosts, }; } else { @@ -125,3 +125,10 @@ function mapToHostResultList( }; } } + +function enrichHostMetadata(hostMetadata: HostMetadata): HostInfo { + return { + metadata: hostMetadata, + host_status: HostStatus.ERROR, + }; +} diff --git a/x-pack/plugins/endpoint/server/routes/metadata/metadata.test.ts b/x-pack/plugins/endpoint/server/routes/metadata/metadata.test.ts index e0fd11e737e7d..9bd251735cc04 100644 --- a/x-pack/plugins/endpoint/server/routes/metadata/metadata.test.ts +++ b/x-pack/plugins/endpoint/server/routes/metadata/metadata.test.ts @@ -18,7 +18,7 @@ import { httpServiceMock, loggingServiceMock, } from '../../../../../../src/core/server/mocks'; -import { HostMetadata, HostResultList } from '../../../common/types'; +import { HostInfo, HostMetadata, HostResultList, HostStatus } from '../../../common/types'; import { SearchResponse } from 'elasticsearch'; import { EndpointConfigSchema } from '../../config'; import * as data from '../../test_data/all_metadata_data.json'; @@ -230,7 +230,7 @@ describe('test endpoint route', () => { expect(message).toEqual('Endpoint Not Found'); }); - it('should return a single endpoint', async () => { + it('should return a single endpoint with status error', async () => { const mockRequest = httpServerMock.createKibanaRequest({ params: { id: (data as any).hits.hits[0]._id }, }); @@ -257,8 +257,9 @@ describe('test endpoint route', () => { expect(mockScopedClient.callAsCurrentUser).toBeCalled(); expect(routeConfig.options).toEqual({ authRequired: true }); expect(mockResponse.ok).toBeCalled(); - const result = mockResponse.ok.mock.calls[0][0]?.body as HostMetadata; - expect(result).toHaveProperty('endpoint'); + const result = mockResponse.ok.mock.calls[0][0]?.body as HostInfo; + expect(result).toHaveProperty('metadata.endpoint'); + expect(result.host_status).toEqual(HostStatus.ERROR); }); }); }); diff --git a/x-pack/test/api_integration/apis/endpoint/metadata.ts b/x-pack/test/api_integration/apis/endpoint/metadata.ts index ad495d4505404..887be6b85b100 100644 --- a/x-pack/test/api_integration/apis/endpoint/metadata.ts +++ b/x-pack/test/api_integration/apis/endpoint/metadata.ts @@ -139,7 +139,7 @@ export default function({ getService }: FtrProviderContext) { .expect(200); expect(body.total).to.eql(2); const resultIps: string[] = [].concat( - ...body.hosts.map((metadata: Record) => metadata.host.ip) + ...body.hosts.map((hostInfo: Record) => hostInfo.metadata.host.ip) ); expect(resultIps).to.eql([ '10.192.213.130', @@ -164,7 +164,7 @@ export default function({ getService }: FtrProviderContext) { .expect(200); expect(body.total).to.eql(2); const resultOsVariantValue: Set = new Set( - body.hosts.map((metadata: Record) => metadata.host.os.variant) + body.hosts.map((hostInfo: Record) => hostInfo.metadata.host.os.variant) ); expect(Array.from(resultOsVariantValue)).to.eql([variantValue]); expect(body.hosts.length).to.eql(2); @@ -182,17 +182,17 @@ export default function({ getService }: FtrProviderContext) { }) .expect(200); expect(body.total).to.eql(1); - const resultIp: string = body.hosts[0].host.ip.filter( + const resultIp: string = body.hosts[0].metadata.host.ip.filter( (ip: string) => ip === targetEndpointIp ); expect(resultIp).to.eql([targetEndpointIp]); - expect(body.hosts[0].event.created).to.eql(1579881969541); + expect(body.hosts[0].metadata.event.created).to.eql(1579881969541); expect(body.hosts.length).to.eql(1); expect(body.request_page_size).to.eql(10); expect(body.request_page_index).to.eql(0); }); - it('metadata api should return the endpoint based on the elastic agent id', async () => { + it('metadata api should return the endpoint based on the elastic agent id, and status should be error', async () => { const targetEndpointId = 'fc0ff548-feba-41b6-8367-65e8790d0eaf'; const targetElasticAgentId = '023fa40c-411d-4188-a941-4147bfadd095'; const { body } = await supertest @@ -203,11 +203,12 @@ export default function({ getService }: FtrProviderContext) { }) .expect(200); expect(body.total).to.eql(1); - const resultHostId: string = body.hosts[0].host.id; - const resultElasticAgentId: string = body.hosts[0].elastic.agent.id; + const resultHostId: string = body.hosts[0].metadata.host.id; + const resultElasticAgentId: string = body.hosts[0].metadata.elastic.agent.id; expect(resultHostId).to.eql(targetEndpointId); expect(resultElasticAgentId).to.eql(targetElasticAgentId); - expect(body.hosts[0].event.created).to.eql(1579881969541); + expect(body.hosts[0].metadata.event.created).to.eql(1579881969541); + expect(body.hosts[0].host_status).to.eql('error'); expect(body.hosts.length).to.eql(1); expect(body.request_page_size).to.eql(10); expect(body.request_page_index).to.eql(0); From 8d8c41153afa90d53004ab872a4ea86ca30a7b37 Mon Sep 17 00:00:00 2001 From: Tim Sullivan Date: Wed, 8 Apr 2020 09:22:06 -0700 Subject: [PATCH 14/40] Reporting/fix listing pagination (#62881) * [Reporting] Fix report table pagination * update snapshot * nice little comment --- .../report_listing.test.tsx.snap | 524 ------------------ .../public/components/report_listing.tsx | 60 +- 2 files changed, 31 insertions(+), 553 deletions(-) diff --git a/x-pack/plugins/reporting/public/components/__snapshots__/report_listing.test.tsx.snap b/x-pack/plugins/reporting/public/components/__snapshots__/report_listing.test.tsx.snap index 75bc1f9eea696..271d61c224210 100644 --- a/x-pack/plugins/reporting/public/components/__snapshots__/report_listing.test.tsx.snap +++ b/x-pack/plugins/reporting/public/components/__snapshots__/report_listing.test.tsx.snap @@ -2,525 +2,6 @@ exports[`ReportListing Report job listing with some items 1`] = ` Array [ - -
- - -
- -
- - - -
-
- - - - -
- - -
-
- - - -
- -
- - - -
- - -
-
- -
- -
- -
- - -
- -
- -
- - -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
-
- - -
- -
-
- - -
-
-
- - Report - -
-
-
- - Created at - -
-
-
- - Status - -
-
-
- - Actions - -
-
-
- - Loading reports - -
-
-
-
-
- -
- , { throw error; } } + + // Since the contents of the table have changed, we must reset the pagination + // and re-fetch. Otherwise, the Nth page we are on could be empty of jobs. + this.setState(() => ({ page: 0 }), this.fetchJobs); }; return ( @@ -476,34 +480,32 @@ class ReportListingUi extends Component { onSelectionChange: this.onSelectionChange, }; - const search = { - toolsRight: this.renderDeleteButton(), - }; - return ( - + + + {this.state.selectedJobs.length > 0 ? this.renderDeleteButton() : null} + ); } } From 18c3f75bfbcf95bc531b0c752c887a0e502b720a Mon Sep 17 00:00:00 2001 From: Phillip Burch Date: Wed, 8 Apr 2020 11:38:23 -0500 Subject: [PATCH 15/40] The theme doesn't exist on props when used from the alerting management screen (#62811) --- .../infra/public/components/alerting/metrics/expression.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/infra/public/components/alerting/metrics/expression.tsx b/x-pack/plugins/infra/public/components/alerting/metrics/expression.tsx index 0903787dd05c4..2e43ede2480ce 100644 --- a/x-pack/plugins/infra/public/components/alerting/metrics/expression.tsx +++ b/x-pack/plugins/infra/public/components/alerting/metrics/expression.tsx @@ -320,11 +320,11 @@ interface ExpressionRowProps { const StyledExpressionRow = euiStyled(EuiFlexGroup)` display: flex; flex-wrap: wrap; - margin: 0 -${props => props.theme.eui.euiSizeXS}; + margin: 0 -4px; `; const StyledExpression = euiStyled.div` - padding: 0 ${props => props.theme.eui.euiSizeXS}; + padding: 0 4px; `; export const ExpressionRow: React.FC = props => { From 730dcbf6382acb50b0c7664ca2b86fb22d5dba7a Mon Sep 17 00:00:00 2001 From: Yuliia Naumenko Date: Wed, 8 Apr 2020 09:54:42 -0700 Subject: [PATCH 16/40] Implemented actions server API for supporting preconfigured connectors (#62382) * Implemented actions server API for supporting preconfigured connectors defined in kibana.yaml * Fixed type check * Fixed due to comments and extended functional tests * Fixed tests and renamed connectors * fixed jest tests * Fixed type checks * Fixed failing alert save * Fixed alert client tests * fixed type checks * Fixed language check error * Fixed jest tests * Added missing comments and docs * fixed due to comments * Fixed json config for preconfigured * fixed type check, reverted config * config experiment with json stringify * revert experiment * Removed the spaces from connector names in config --- .../__snapshots__/step1.test.tsx.snap | 1 + .../alerts/configuration/configuration.tsx | 2 +- .../alerts/configuration/step1.test.tsx | 2 + .../public/containers/case/configure/api.ts | 4 +- .../case/configure/use_connectors.tsx | 2 +- .../configure_cases/__mock__/index.tsx | 2 + .../routes/__mocks__/request_responses.ts | 2 + .../scripts/get_action_instances.sh | 2 +- x-pack/plugins/actions/README.md | 11 +- x-pack/plugins/actions/common/types.ts | 1 + .../actions/server/actions_client.mock.ts | 2 +- .../actions/server/actions_client.test.ts | 94 ++++++-- .../plugins/actions/server/actions_client.ts | 116 +++++---- x-pack/plugins/actions/server/config.test.ts | 38 +++ x-pack/plugins/actions/server/config.ts | 12 + x-pack/plugins/actions/server/index.ts | 8 +- ...configured_action_disabled_modification.ts | 24 ++ x-pack/plugins/actions/server/mocks.ts | 1 + x-pack/plugins/actions/server/plugin.test.ts | 33 ++- x-pack/plugins/actions/server/plugin.ts | 30 ++- .../plugins/actions/server/routes/delete.ts | 13 +- .../actions/server/routes/find.test.ts | 152 ------------ x-pack/plugins/actions/server/routes/find.ts | 95 -------- .../actions/server/routes/get_all.test.ts | 117 ++++++++++ .../plugins/actions/server/routes/get_all.ts | 42 ++++ x-pack/plugins/actions/server/routes/index.ts | 2 +- x-pack/plugins/actions/server/types.ts | 5 + .../alerting/server/alerts_client.test.ts | 1 + .../plugins/alerting/server/alerts_client.ts | 52 ++++- .../server/alerts_client_factory.test.ts | 2 + .../alerting/server/alerts_client_factory.ts | 5 + x-pack/plugins/alerting/server/plugin.ts | 1 + .../case/common/api/cases/configure.ts | 7 - .../api/cases/configure/get_connectors.ts | 10 +- .../builtin_action_types/email.test.tsx | 4 + .../builtin_action_types/webhook.test.tsx | 2 + .../lib/action_connector_api.test.ts | 25 +- .../application/lib/action_connector_api.ts | 24 +- .../action_form.test.tsx | 15 ++ .../action_connector_form/action_form.tsx | 2 +- .../connector_edit_flyout.test.tsx | 1 + .../connector_reducer.test.ts | 1 + .../actions_connectors_list.test.tsx | 125 ++++------ .../components/actions_connectors_list.tsx | 2 +- .../components/alerts_list.test.tsx | 28 +-- .../triggers_actions_ui/public/types.ts | 1 + .../alerting_api_integration/common/config.ts | 24 ++ .../actions/builtin_action_types/email.ts | 2 + .../actions/builtin_action_types/es_index.ts | 4 + .../actions/builtin_action_types/pagerduty.ts | 2 + .../builtin_action_types/server_log.ts | 2 + .../builtin_action_types/servicenow.ts | 2 + .../actions/builtin_action_types/slack.ts | 2 + .../actions/builtin_action_types/webhook.ts | 2 + .../tests/actions/create.ts | 1 + .../tests/actions/delete.ts | 30 +++ .../security_and_spaces/tests/actions/get.ts | 35 +++ .../tests/actions/{find.ts => get_all.ts} | 220 +++++++++--------- .../tests/actions/index.ts | 2 +- .../tests/actions/update.ts | 40 ++++ .../actions/builtin_action_types/es_index.ts | 4 + .../spaces_only/tests/actions/create.ts | 1 + .../spaces_only/tests/actions/delete.ts | 11 + .../spaces_only/tests/actions/find.ts | 92 -------- .../spaces_only/tests/actions/get.ts | 13 ++ .../spaces_only/tests/actions/get_all.ts | 116 +++++++++ .../spaces_only/tests/actions/index.ts | 2 +- .../tests/actions/type_not_enabled.ts | 2 + .../spaces_only/tests/actions/update.ts | 21 ++ 69 files changed, 1050 insertions(+), 701 deletions(-) create mode 100644 x-pack/plugins/actions/server/lib/errors/preconfigured_action_disabled_modification.ts delete mode 100644 x-pack/plugins/actions/server/routes/find.test.ts delete mode 100644 x-pack/plugins/actions/server/routes/find.ts create mode 100644 x-pack/plugins/actions/server/routes/get_all.test.ts create mode 100644 x-pack/plugins/actions/server/routes/get_all.ts rename x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/{find.ts => get_all.ts} (57%) delete mode 100644 x-pack/test/alerting_api_integration/spaces_only/tests/actions/find.ts create mode 100644 x-pack/test/alerting_api_integration/spaces_only/tests/actions/get_all.ts diff --git a/x-pack/legacy/plugins/monitoring/public/components/alerts/configuration/__snapshots__/step1.test.tsx.snap b/x-pack/legacy/plugins/monitoring/public/components/alerts/configuration/__snapshots__/step1.test.tsx.snap index 94d951a94fe29..cb1081c0c14da 100644 --- a/x-pack/legacy/plugins/monitoring/public/components/alerts/configuration/__snapshots__/step1.test.tsx.snap +++ b/x-pack/legacy/plugins/monitoring/public/components/alerts/configuration/__snapshots__/step1.test.tsx.snap @@ -25,6 +25,7 @@ exports[`Step1 editing should allow for editing 1`] = ` "actionTypeId": "1abc", "config": Object {}, "id": "1", + "isPreconfigured": false, "name": "Testing", } } diff --git a/x-pack/legacy/plugins/monitoring/public/components/alerts/configuration/configuration.tsx b/x-pack/legacy/plugins/monitoring/public/components/alerts/configuration/configuration.tsx index 0933cd22db7c9..eaa474ba177b1 100644 --- a/x-pack/legacy/plugins/monitoring/public/components/alerts/configuration/configuration.tsx +++ b/x-pack/legacy/plugins/monitoring/public/components/alerts/configuration/configuration.tsx @@ -61,7 +61,7 @@ export const AlertsConfiguration: React.FC = ( async function fetchEmailActions() { const kibanaActions = await kfetch({ method: 'GET', - pathname: `/api/action/_find`, + pathname: `/api/action/_getAll`, }); const actions = kibanaActions.data.filter( diff --git a/x-pack/legacy/plugins/monitoring/public/components/alerts/configuration/step1.test.tsx b/x-pack/legacy/plugins/monitoring/public/components/alerts/configuration/step1.test.tsx index 650294c29e9a5..19a1a61d00a42 100644 --- a/x-pack/legacy/plugins/monitoring/public/components/alerts/configuration/step1.test.tsx +++ b/x-pack/legacy/plugins/monitoring/public/components/alerts/configuration/step1.test.tsx @@ -27,6 +27,7 @@ describe('Step1', () => { actionTypeId: '1abc', name: 'Testing', config: {}, + isPreconfigured: false, }, ]; const selectedEmailActionId = emailActions[0].id; @@ -83,6 +84,7 @@ describe('Step1', () => { actionTypeId: '.email', name: '', config: {}, + isPreconfigured: false, }, ], selectedEmailActionId: NEW_ACTION_ID, diff --git a/x-pack/legacy/plugins/siem/public/containers/case/configure/api.ts b/x-pack/legacy/plugins/siem/public/containers/case/configure/api.ts index ed47cdc62a1b6..c24081c777a96 100644 --- a/x-pack/legacy/plugins/siem/public/containers/case/configure/api.ts +++ b/x-pack/legacy/plugins/siem/public/containers/case/configure/api.ts @@ -6,7 +6,7 @@ import { isEmpty } from 'lodash/fp'; import { - CasesConnectorsFindResult, + Connector, CasesConfigurePatch, CasesConfigureResponse, CasesConfigureRequest, @@ -18,7 +18,7 @@ import { ApiProps } from '../types'; import { convertToCamelCase, decodeCaseConfigureResponse } from '../utils'; import { CaseConfigure } from './types'; -export const fetchConnectors = async ({ signal }: ApiProps): Promise => { +export const fetchConnectors = async ({ signal }: ApiProps): Promise => { const response = await KibanaServices.get().http.fetch( `${CASES_CONFIGURE_URL}/connectors/_find`, { diff --git a/x-pack/legacy/plugins/siem/public/containers/case/configure/use_connectors.tsx b/x-pack/legacy/plugins/siem/public/containers/case/configure/use_connectors.tsx index d31dcdbee2a14..30108ecf33874 100644 --- a/x-pack/legacy/plugins/siem/public/containers/case/configure/use_connectors.tsx +++ b/x-pack/legacy/plugins/siem/public/containers/case/configure/use_connectors.tsx @@ -31,7 +31,7 @@ export const useConnectors = (): ReturnConnectors => { const res = await fetchConnectors({ signal: abortCtrl.signal }); if (!didCancel) { setLoading(false); - setConnectors(res.data); + setConnectors(res); } } catch (error) { if (!didCancel) { diff --git a/x-pack/legacy/plugins/siem/public/pages/case/components/configure_cases/__mock__/index.tsx b/x-pack/legacy/plugins/siem/public/pages/case/components/configure_cases/__mock__/index.tsx index a3df3664398ad..135f0f2a7e26d 100644 --- a/x-pack/legacy/plugins/siem/public/pages/case/components/configure_cases/__mock__/index.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/case/components/configure_cases/__mock__/index.tsx @@ -21,6 +21,7 @@ export const connectors: Connector[] = [ id: '123', actionTypeId: '.servicenow', name: 'My Connector', + isPreconfigured: false, config: { apiUrl: 'https://instance1.service-now.com', casesConfiguration: { @@ -48,6 +49,7 @@ export const connectors: Connector[] = [ id: '456', actionTypeId: '.servicenow', name: 'My Connector 2', + isPreconfigured: false, config: { apiUrl: 'https://instance2.service-now.com', casesConfiguration: { diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/__mocks__/request_responses.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/__mocks__/request_responses.ts index 77c1641d073c6..e400360a5a5b2 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/__mocks__/request_responses.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/__mocks__/request_responses.ts @@ -383,6 +383,7 @@ export const createActionResult = (): ActionResult => ({ actionTypeId: 'action-id-1', name: '', config: {}, + isPreconfigured: false, }); export const nonRuleAlert = () => ({ @@ -518,6 +519,7 @@ export const updateActionResult = (): ActionResult => ({ actionTypeId: 'action-id-1', name: '', config: {}, + isPreconfigured: false, }); export const getMockPrivilegesResult = () => ({ diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/scripts/get_action_instances.sh b/x-pack/legacy/plugins/siem/server/lib/detection_engine/scripts/get_action_instances.sh index 7804439ce0734..750c5574f4a72 100755 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/scripts/get_action_instances.sh +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/scripts/get_action_instances.sh @@ -13,5 +13,5 @@ set -e # https://github.com/elastic/kibana/blob/master/x-pack/legacy/plugins/actions/README.md#get-apiaction_find-find-actions curl -s -k \ -u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \ - -X GET ${KIBANA_URL}${SPACE_URL}/api/action/_find \ + -X GET ${KIBANA_URL}${SPACE_URL}/api/action/_getAll \ | jq . diff --git a/x-pack/plugins/actions/README.md b/x-pack/plugins/actions/README.md index d217d26e84836..82cc09f5e9eca 100644 --- a/x-pack/plugins/actions/README.md +++ b/x-pack/plugins/actions/README.md @@ -28,7 +28,7 @@ Table of Contents - [RESTful API](#restful-api) - [`POST /api/action`: Create action](#post-apiaction-create-action) - [`DELETE /api/action/{id}`: Delete action](#delete-apiactionid-delete-action) - - [`GET /api/action/_find`: Find actions](#get-apiactionfind-find-actions) + - [`GET /api/action/_getAll`: Get all actions](#get-apiaction-get-all-actions) - [`GET /api/action/{id}`: Get action](#get-apiactionid-get-action) - [`GET /api/action/types`: List action types](#get-apiactiontypes-list-action-types) - [`PUT /api/action/{id}`: Update action](#put-apiactionid-update-action) @@ -92,6 +92,7 @@ Built-In-Actions are configured using the _xpack.actions_ namespoace under _kiba | _xpack.actions._**enabled** | Feature toggle which enabled Actions in Kibana. | boolean | | _xpack.actions._**whitelistedHosts** | Which _hostnames_ are whitelisted for the Built-In-Action? This list should contain hostnames of every external service you wish to interact with using Webhooks, Email or any other built in Action. Note that you may use the string "\*" in place of a specific hostname to enable Kibana to target any URL, but keep in mind the potential use of such a feature to execute [SSRF](https://www.owasp.org/index.php/Server_Side_Request_Forgery) attacks from your server. | Array | | _xpack.actions._**enabledActionTypes** | A list of _actionTypes_ id's that are enabled. A "\*" may be used as an element to indicate all registered actionTypes should be enabled. The actionTypes registered for Kibana are `.server-log`, `.slack`, `.email`, `.index`, `.pagerduty`, `.webhook`. Default: `["*"]` | Array | +| _xpack.actions._**preconfigured** | A list of preconfigured actions. Default: `[]` | Array | #### Whitelisting Built-in Action Types @@ -174,11 +175,13 @@ Params: | -------- | --------------------------------------------- | ------ | | id | The id of the action you're trying to delete. | string | -### `GET /api/action/_find`: Find actions +### `GET /api/action/_getAll`: Get all actions -Params: +No parameters. -See the [saved objects API documentation for find](https://www.elastic.co/guide/en/kibana/master/saved-objects-api-find.html). All the properties are the same except that you cannot pass in `type`. +Return all actions from saved objects merged with predefined list. +Use the [saved objects API for find](https://www.elastic.co/guide/en/kibana/master/saved-objects-api-find.html) with the proprties: `type: 'action'` and `perPage: 10000`. +List of predefined actions should be set up in Kibana.yaml. ### `GET /api/action/{id}`: Get action diff --git a/x-pack/plugins/actions/common/types.ts b/x-pack/plugins/actions/common/types.ts index f3042a701211f..61b338d47b9f5 100644 --- a/x-pack/plugins/actions/common/types.ts +++ b/x-pack/plugins/actions/common/types.ts @@ -20,4 +20,5 @@ export interface ActionResult { actionTypeId: string; name: string; config: Record; + isPreconfigured: boolean; } diff --git a/x-pack/plugins/actions/server/actions_client.mock.ts b/x-pack/plugins/actions/server/actions_client.mock.ts index 8a39d68f40bb6..431bfb1e99c3b 100644 --- a/x-pack/plugins/actions/server/actions_client.mock.ts +++ b/x-pack/plugins/actions/server/actions_client.mock.ts @@ -12,9 +12,9 @@ const createActionsClientMock = () => { const mocked: jest.Mocked = { create: jest.fn(), get: jest.fn(), - find: jest.fn(), delete: jest.fn(), update: jest.fn(), + getAll: jest.fn(), }; return mocked; }; diff --git a/x-pack/plugins/actions/server/actions_client.test.ts b/x-pack/plugins/actions/server/actions_client.test.ts index 0df07ad58fb9e..955e1569380a5 100644 --- a/x-pack/plugins/actions/server/actions_client.test.ts +++ b/x-pack/plugins/actions/server/actions_client.test.ts @@ -51,6 +51,7 @@ beforeEach(() => { savedObjectsClient, scopedClusterClient, defaultKibanaIndex, + preconfiguredActions: [], }); }); @@ -83,6 +84,7 @@ describe('create()', () => { }); expect(result).toEqual({ id: '1', + isPreconfigured: false, name: 'my name', actionTypeId: 'my-action-type', config: {}, @@ -178,6 +180,7 @@ describe('create()', () => { }); expect(result).toEqual({ id: '1', + isPreconfigured: false, name: 'my name', actionTypeId: 'my-action-type', config: { @@ -226,6 +229,7 @@ describe('create()', () => { savedObjectsClient, scopedClusterClient, defaultKibanaIndex, + preconfiguredActions: [], }); const savedObjectCreateResult = { @@ -305,6 +309,7 @@ describe('get()', () => { const result = await actionsClient.get({ id: '1' }); expect(result).toEqual({ id: '1', + isPreconfigured: false, }); expect(savedObjectsClient.get).toHaveBeenCalledTimes(1); expect(savedObjectsClient.get.mock.calls[0]).toMatchInlineSnapshot(` @@ -314,9 +319,44 @@ describe('get()', () => { ] `); }); + + test('return predefined action with id', async () => { + actionsClient = new ActionsClient({ + actionTypeRegistry, + savedObjectsClient, + scopedClusterClient, + defaultKibanaIndex, + preconfiguredActions: [ + { + id: 'testPreconfigured', + actionTypeId: '.slack', + secrets: { + test: 'test1', + }, + isPreconfigured: true, + name: 'test', + config: { + foo: 'bar', + }, + }, + ], + }); + + const result = await actionsClient.get({ id: 'testPreconfigured' }); + expect(result).toEqual({ + id: 'testPreconfigured', + actionTypeId: '.slack', + isPreconfigured: true, + name: 'test', + config: { + foo: 'bar', + }, + }); + expect(savedObjectsClient.get).not.toHaveBeenCalled(); + }); }); -describe('find()', () => { +describe('getAll()', () => { test('calls savedObjectsClient with parameters', async () => { const expectedResult = { total: 1, @@ -327,6 +367,7 @@ describe('find()', () => { id: '1', type: 'type', attributes: { + name: 'test', config: { foo: 'bar', }, @@ -339,31 +380,50 @@ describe('find()', () => { scopedClusterClient.callAsInternalUser.mockResolvedValueOnce({ aggregations: { '1': { doc_count: 6 }, + testPreconfigured: { doc_count: 2 }, }, }); - const result = await actionsClient.find({}); - expect(result).toEqual({ - total: 1, - perPage: 10, - page: 1, - data: [ + + actionsClient = new ActionsClient({ + actionTypeRegistry, + savedObjectsClient, + scopedClusterClient, + defaultKibanaIndex, + preconfiguredActions: [ { - id: '1', + id: 'testPreconfigured', + actionTypeId: '.slack', + secrets: {}, + isPreconfigured: true, + name: 'test', config: { foo: 'bar', }, - referencedByCount: 6, }, ], }); - expect(savedObjectsClient.find).toHaveBeenCalledTimes(1); - expect(savedObjectsClient.find.mock.calls[0]).toMatchInlineSnapshot(` - Array [ - Object { - "type": "action", + const result = await actionsClient.getAll(); + expect(result).toEqual([ + { + id: '1', + isPreconfigured: false, + name: 'test', + config: { + foo: 'bar', }, - ] - `); + referencedByCount: 6, + }, + { + id: 'testPreconfigured', + actionTypeId: '.slack', + isPreconfigured: true, + name: 'test', + config: { + foo: 'bar', + }, + referencedByCount: 2, + }, + ]); }); }); @@ -420,6 +480,7 @@ describe('update()', () => { }); expect(result).toEqual({ id: 'my-action', + isPreconfigured: false, actionTypeId: 'my-action-type', name: 'my name', config: {}, @@ -524,6 +585,7 @@ describe('update()', () => { }); expect(result).toEqual({ id: 'my-action', + isPreconfigured: false, actionTypeId: 'my-action-type', name: 'my name', config: { diff --git a/x-pack/plugins/actions/server/actions_client.ts b/x-pack/plugins/actions/server/actions_client.ts index 129829850f9c1..8f73bfb31ea4d 100644 --- a/x-pack/plugins/actions/server/actions_client.ts +++ b/x-pack/plugins/actions/server/actions_client.ts @@ -11,9 +11,16 @@ import { SavedObject, } from 'src/core/server'; +import { i18n } from '@kbn/i18n'; import { ActionTypeRegistry } from './action_type_registry'; import { validateConfig, validateSecrets } from './lib'; -import { ActionResult, FindActionResult, RawAction } from './types'; +import { ActionResult, FindActionResult, RawAction, PreConfiguredAction } from './types'; +import { PreconfiguredActionDisabledModificationError } from './lib/errors/preconfigured_action_disabled_modification'; + +// We are assuming there won't be many actions. This is why we will load +// all the actions in advance and assume the total count to not go over 10000. +// We'll set this max setting assuming it's never reached. +export const MAX_ACTIONS_RETURNED = 10000; interface ActionUpdate extends SavedObjectAttributes { name: string; @@ -29,35 +36,12 @@ interface CreateOptions { action: Action; } -interface FindOptions { - options?: { - perPage?: number; - page?: number; - search?: string; - defaultSearchOperator?: 'AND' | 'OR'; - searchFields?: string[]; - sortField?: string; - hasReference?: { - type: string; - id: string; - }; - fields?: string[]; - filter?: string; - }; -} - -interface FindResult { - page: number; - perPage: number; - total: number; - data: FindActionResult[]; -} - interface ConstructorOptions { defaultKibanaIndex: string; scopedClusterClient: IScopedClusterClient; actionTypeRegistry: ActionTypeRegistry; savedObjectsClient: SavedObjectsClientContract; + preconfiguredActions: PreConfiguredAction[]; } interface UpdateOptions { @@ -70,17 +54,20 @@ export class ActionsClient { private readonly scopedClusterClient: IScopedClusterClient; private readonly savedObjectsClient: SavedObjectsClientContract; private readonly actionTypeRegistry: ActionTypeRegistry; + private readonly preconfiguredActions: PreConfiguredAction[]; constructor({ actionTypeRegistry, defaultKibanaIndex, scopedClusterClient, savedObjectsClient, + preconfiguredActions, }: ConstructorOptions) { this.actionTypeRegistry = actionTypeRegistry; this.savedObjectsClient = savedObjectsClient; this.scopedClusterClient = scopedClusterClient; this.defaultKibanaIndex = defaultKibanaIndex; + this.preconfiguredActions = preconfiguredActions; } /** @@ -106,6 +93,7 @@ export class ActionsClient { actionTypeId: result.attributes.actionTypeId, name: result.attributes.name, config: result.attributes.config, + isPreconfigured: false, }; } @@ -113,6 +101,20 @@ export class ActionsClient { * Update action */ public async update({ id, action }: UpdateOptions): Promise { + if ( + this.preconfiguredActions.find(preconfiguredAction => preconfiguredAction.id === id) !== + undefined + ) { + throw new PreconfiguredActionDisabledModificationError( + i18n.translate('xpack.actions.serverSideErrors.predefinedActionUpdateDisabled', { + defaultMessage: 'Preconfigured action {id} is not allowed to update.', + values: { + id, + }, + }), + 'update' + ); + } const existingObject = await this.savedObjectsClient.get('action', id); const { actionTypeId } = existingObject.attributes; const { name, config, secrets } = action; @@ -134,6 +136,7 @@ export class ActionsClient { actionTypeId: result.attributes.actionTypeId as string, name: result.attributes.name as string, config: result.attributes.config as Record, + isPreconfigured: false, }; } @@ -141,6 +144,18 @@ export class ActionsClient { * Get an action */ public async get({ id }: { id: string }): Promise { + const preconfiguredActionsList = this.preconfiguredActions.find( + preconfiguredAction => preconfiguredAction.id === id + ); + if (preconfiguredActionsList !== undefined) { + return { + id, + actionTypeId: preconfiguredActionsList.actionTypeId, + name: preconfiguredActionsList.name, + config: preconfiguredActionsList.config, + isPreconfigured: true, + }; + } const result = await this.savedObjectsClient.get('action', id); return { @@ -148,36 +163,56 @@ export class ActionsClient { actionTypeId: result.attributes.actionTypeId, name: result.attributes.name, config: result.attributes.config, + isPreconfigured: false, }; } /** - * Find actions + * Get all actions with preconfigured list */ - public async find({ options = {} }: FindOptions): Promise { - const findResult = await this.savedObjectsClient.find({ - ...options, - type: 'action', - }); + public async getAll(): Promise { + const savedObjectsActions = ( + await this.savedObjectsClient.find({ + perPage: MAX_ACTIONS_RETURNED, + type: 'action', + }) + ).saved_objects.map(actionFromSavedObject); - const data = await injectExtraFindData( + const mergedResult = [ + ...savedObjectsActions, + ...this.preconfiguredActions.map(preconfiguredAction => ({ + id: preconfiguredAction.id, + actionTypeId: preconfiguredAction.actionTypeId, + name: preconfiguredAction.name, + config: preconfiguredAction.config, + isPreconfigured: true, + })), + ].sort((a, b) => a.name.localeCompare(b.name)); + return await injectExtraFindData( this.defaultKibanaIndex, this.scopedClusterClient, - findResult.saved_objects.map(actionFromSavedObject) + mergedResult ); - - return { - page: findResult.page, - perPage: findResult.per_page, - total: findResult.total, - data, - }; } /** * Delete action */ public async delete({ id }: { id: string }) { + if ( + this.preconfiguredActions.find(preconfiguredAction => preconfiguredAction.id === id) !== + undefined + ) { + throw new PreconfiguredActionDisabledModificationError( + i18n.translate('xpack.actions.serverSideErrors.predefinedActionDeleteDisabled', { + defaultMessage: 'Preconfigured action {id} is not allowed to delete.', + values: { + id, + }, + }), + 'delete' + ); + } return await this.savedObjectsClient.delete('action', id); } } @@ -186,6 +221,7 @@ function actionFromSavedObject(savedObject: SavedObject): ActionResul return { id: savedObject.id, ...savedObject.attributes, + isPreconfigured: false, }; } diff --git a/x-pack/plugins/actions/server/config.test.ts b/x-pack/plugins/actions/server/config.test.ts index 67b7553c4a736..51e87dbd75b48 100644 --- a/x-pack/plugins/actions/server/config.test.ts +++ b/x-pack/plugins/actions/server/config.test.ts @@ -14,6 +14,44 @@ describe('config validation', () => { "enabledActionTypes": Array [ "*", ], + "preconfigured": Array [], + "whitelistedHosts": Array [ + "*", + ], + } + `); + }); + + test('action with preconfigured actions', () => { + const config: Record = { + preconfigured: [ + { + id: 'my-slack1', + actionTypeId: '.slack', + name: 'Slack #xyz', + config: { + webhookUrl: 'https://hooks.slack.com/services/abcd/efgh/ijklmnopqrstuvwxyz', + }, + }, + ], + }; + expect(configSchema.validate(config)).toMatchInlineSnapshot(` + Object { + "enabled": true, + "enabledActionTypes": Array [ + "*", + ], + "preconfigured": Array [ + Object { + "actionTypeId": ".slack", + "config": Object { + "webhookUrl": "https://hooks.slack.com/services/abcd/efgh/ijklmnopqrstuvwxyz", + }, + "id": "my-slack1", + "name": "Slack #xyz", + "secrets": Object {}, + }, + ], "whitelistedHosts": Array [ "*", ], diff --git a/x-pack/plugins/actions/server/config.ts b/x-pack/plugins/actions/server/config.ts index 9e4795be6c208..1f04efd1941b4 100644 --- a/x-pack/plugins/actions/server/config.ts +++ b/x-pack/plugins/actions/server/config.ts @@ -21,6 +21,18 @@ export const configSchema = schema.object({ defaultValue: [WhitelistedHosts.Any], } ), + preconfigured: schema.arrayOf( + schema.object({ + id: schema.string({ minLength: 1 }), + name: schema.string(), + actionTypeId: schema.string({ minLength: 1 }), + config: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }), + secrets: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }), + }), + { + defaultValue: [], + } + ), }); export type ActionsConfig = TypeOf; diff --git a/x-pack/plugins/actions/server/index.ts b/x-pack/plugins/actions/server/index.ts index eee2ae352fe3d..88553c314112f 100644 --- a/x-pack/plugins/actions/server/index.ts +++ b/x-pack/plugins/actions/server/index.ts @@ -11,7 +11,13 @@ import { ActionsClient as ActionsClientClass } from './actions_client'; export type ActionsClient = PublicMethodsOf; -export { ActionsPlugin, ActionResult, ActionTypeExecutorOptions, ActionType } from './types'; +export { + ActionsPlugin, + ActionResult, + ActionTypeExecutorOptions, + ActionType, + PreConfiguredAction, +} from './types'; export { PluginSetupContract, PluginStartContract } from './plugin'; export const plugin = (initContext: PluginInitializerContext) => new ActionsPlugin(initContext); diff --git a/x-pack/plugins/actions/server/lib/errors/preconfigured_action_disabled_modification.ts b/x-pack/plugins/actions/server/lib/errors/preconfigured_action_disabled_modification.ts new file mode 100644 index 0000000000000..884353e132b9c --- /dev/null +++ b/x-pack/plugins/actions/server/lib/errors/preconfigured_action_disabled_modification.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 { KibanaResponseFactory } from '../../../../../../src/core/server'; +import { ErrorThatHandlesItsOwnResponse } from './types'; + +export type PreconfiguredActionDisabledFrom = 'update' | 'delete'; + +export class PreconfiguredActionDisabledModificationError extends Error + implements ErrorThatHandlesItsOwnResponse { + public readonly disabledFrom: PreconfiguredActionDisabledFrom; + + constructor(message: string, disabledFrom: PreconfiguredActionDisabledFrom) { + super(message); + this.disabledFrom = disabledFrom; + } + + public sendResponse(res: KibanaResponseFactory) { + return res.badRequest({ body: { message: this.message } }); + } +} diff --git a/x-pack/plugins/actions/server/mocks.ts b/x-pack/plugins/actions/server/mocks.ts index 75396f2aad897..bc4268bb69872 100644 --- a/x-pack/plugins/actions/server/mocks.ts +++ b/x-pack/plugins/actions/server/mocks.ts @@ -21,6 +21,7 @@ const createStartMock = () => { execute: jest.fn(), isActionTypeEnabled: jest.fn(), getActionsClientWithRequest: jest.fn().mockResolvedValue(actionsClientMock.create()), + preconfiguredActions: [], }; return mock; }; diff --git a/x-pack/plugins/actions/server/plugin.test.ts b/x-pack/plugins/actions/server/plugin.test.ts index 383f84590fbc6..6215b08df81d4 100644 --- a/x-pack/plugins/actions/server/plugin.test.ts +++ b/x-pack/plugins/actions/server/plugin.test.ts @@ -31,7 +31,34 @@ describe('Actions Plugin', () => { let pluginsSetup: jest.Mocked; beforeEach(() => { - context = coreMock.createPluginInitializerContext(); + context = coreMock.createPluginInitializerContext({ + preconfigured: [ + { + id: 'my-slack1', + actionTypeId: '.slack', + name: 'Slack #xyz', + description: 'Send a message to the #xyz channel', + config: { + webhookUrl: 'https://hooks.slack.com/services/abcd/efgh/ijklmnopqrstuvwxyz', + }, + }, + { + id: 'custom-system-abc-connector', + actionTypeId: 'system-abc-action-type', + description: 'Send a notification to system ABC', + name: 'System ABC', + config: { + xyzConfig1: 'value1', + xyzConfig2: 'value2', + listOfThings: ['a', 'b', 'c', 'd'], + }, + secrets: { + xyzSecret1: 'credential1', + xyzSecret2: 'credential2', + }, + }, + ], + }); plugin = new ActionsPlugin(context); coreSetup = coreMock.createSetup(); @@ -160,7 +187,9 @@ describe('Actions Plugin', () => { let pluginsStart: jest.Mocked; beforeEach(() => { - const context = coreMock.createPluginInitializerContext(); + const context = coreMock.createPluginInitializerContext({ + preconfigured: [], + }); plugin = new ActionsPlugin(context); coreSetup = coreMock.createSetup(); coreStart = coreMock.createStart(); diff --git a/x-pack/plugins/actions/server/plugin.ts b/x-pack/plugins/actions/server/plugin.ts index ce31e62bc9b8e..34c9e7aa9e8b8 100644 --- a/x-pack/plugins/actions/server/plugin.ts +++ b/x-pack/plugins/actions/server/plugin.ts @@ -30,7 +30,7 @@ import { LICENSE_TYPE } from '../../licensing/common/types'; import { SpacesPluginSetup, SpacesServiceSetup } from '../../spaces/server'; import { ActionsConfig } from './config'; -import { Services, ActionType } from './types'; +import { Services, ActionType, PreConfiguredAction } from './types'; import { ActionExecutor, TaskRunnerFactory, LicenseState, ILicenseState } from './lib'; import { ActionsClient } from './actions_client'; import { ActionTypeRegistry } from './action_type_registry'; @@ -44,7 +44,7 @@ import { getActionsConfigurationUtilities } from './actions_config'; import { createActionRoute, deleteActionRoute, - findActionRoute, + getAllActionRoute, getActionRoute, updateActionRoute, listActionTypesRoute, @@ -67,6 +67,7 @@ export interface PluginStartContract { isActionTypeEnabled(id: string): boolean; execute(options: ExecuteOptions): Promise; getActionsClientWithRequest(request: KibanaRequest): Promise>; + preconfiguredActions: PreConfiguredAction[]; } export interface ActionsPluginsSetup { @@ -97,6 +98,7 @@ export class ActionsPlugin implements Plugin, Plugi private eventLogger?: IEventLogger; private isESOUsingEphemeralEncryptionKey?: boolean; private readonly telemetryLogger: Logger; + private readonly preconfiguredActions: PreConfiguredAction[]; constructor(initContext: PluginInitializerContext) { this.config = initContext.config @@ -113,6 +115,7 @@ export class ActionsPlugin implements Plugin, Plugi this.logger = initContext.logger.get('actions'); this.telemetryLogger = initContext.logger.get('telemetry'); + this.preconfiguredActions = []; } public async setup(core: CoreSetup, plugins: ActionsPluginsSetup): Promise { @@ -151,8 +154,14 @@ export class ActionsPlugin implements Plugin, Plugi // get executions count const taskRunnerFactory = new TaskRunnerFactory(actionExecutor); - const actionsConfigUtils = getActionsConfigurationUtilities( - (await this.config) as ActionsConfig + const actionsConfig = (await this.config) as ActionsConfig; + const actionsConfigUtils = getActionsConfigurationUtilities(actionsConfig); + + this.preconfiguredActions.push( + ...actionsConfig.preconfigured.map( + preconfiguredAction => + ({ ...preconfiguredAction, isPreconfigured: true } as PreConfiguredAction) + ) ); const actionTypeRegistry = new ActionTypeRegistry({ taskRunnerFactory, @@ -197,7 +206,7 @@ export class ActionsPlugin implements Plugin, Plugi createActionRoute(router, this.licenseState); deleteActionRoute(router, this.licenseState); getActionRoute(router, this.licenseState); - findActionRoute(router, this.licenseState); + getAllActionRoute(router, this.licenseState); updateActionRoute(router, this.licenseState); listActionTypesRoute(router, this.licenseState); executeActionRoute(router, this.licenseState, actionExecutor); @@ -226,6 +235,7 @@ export class ActionsPlugin implements Plugin, Plugi kibanaIndex, adminClient, isESOUsingEphemeralEncryptionKey, + preconfiguredActions, } = this; actionExecutor!.initialize({ @@ -271,8 +281,10 @@ export class ActionsPlugin implements Plugin, Plugi actionTypeRegistry: actionTypeRegistry!, defaultKibanaIndex: await kibanaIndex, scopedClusterClient: adminClient!.asScoped(request), + preconfiguredActions, }); }, + preconfiguredActions, }; } @@ -289,7 +301,12 @@ export class ActionsPlugin implements Plugin, Plugi private createRouteHandlerContext = ( defaultKibanaIndex: string ): IContextProvider, 'actions'> => { - const { actionTypeRegistry, adminClient, isESOUsingEphemeralEncryptionKey } = this; + const { + actionTypeRegistry, + adminClient, + isESOUsingEphemeralEncryptionKey, + preconfiguredActions, + } = this; return async function actionsRouteHandlerContext(context, request) { return { getActionsClient: () => { @@ -303,6 +320,7 @@ export class ActionsPlugin implements Plugin, Plugi actionTypeRegistry: actionTypeRegistry!, defaultKibanaIndex, scopedClusterClient: adminClient!.asScoped(request), + preconfiguredActions, }); }, listTypes: actionTypeRegistry!.list.bind(actionTypeRegistry!), diff --git a/x-pack/plugins/actions/server/routes/delete.ts b/x-pack/plugins/actions/server/routes/delete.ts index cddebb3a8e31e..ffd1f0faabbab 100644 --- a/x-pack/plugins/actions/server/routes/delete.ts +++ b/x-pack/plugins/actions/server/routes/delete.ts @@ -17,7 +17,7 @@ import { IKibanaResponse, KibanaResponseFactory, } from 'kibana/server'; -import { ILicenseState, verifyApiAccess } from '../lib'; +import { ILicenseState, verifyApiAccess, isErrorThatHandlesItsOwnResponse } from '../lib'; import { BASE_ACTION_API_PATH } from '../../common'; const paramSchema = schema.object({ @@ -46,8 +46,15 @@ export const deleteActionRoute = (router: IRouter, licenseState: ILicenseState) } const actionsClient = context.actions.getActionsClient(); const { id } = req.params; - await actionsClient.delete({ id }); - return res.noContent(); + try { + await actionsClient.delete({ id }); + return res.noContent(); + } catch (e) { + if (isErrorThatHandlesItsOwnResponse(e)) { + return e.sendResponse(res); + } + throw e; + } }) ); }; diff --git a/x-pack/plugins/actions/server/routes/find.test.ts b/x-pack/plugins/actions/server/routes/find.test.ts deleted file mode 100644 index 1b130421fa71f..0000000000000 --- a/x-pack/plugins/actions/server/routes/find.test.ts +++ /dev/null @@ -1,152 +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 { findActionRoute } from './find'; -import { mockRouter, RouterMock } from '../../../../../src/core/server/http/router/router.mock'; -import { licenseStateMock } from '../lib/license_state.mock'; -import { verifyApiAccess } from '../lib'; -import { mockHandlerArguments } from './_mock_handler_arguments'; - -jest.mock('../lib/verify_api_access.ts', () => ({ - verifyApiAccess: jest.fn(), -})); - -beforeEach(() => { - jest.resetAllMocks(); -}); - -describe('findActionRoute', () => { - it('finds actions with proper parameters', async () => { - const licenseState = licenseStateMock.create(); - const router: RouterMock = mockRouter.create(); - - findActionRoute(router, licenseState); - - const [config, handler] = router.get.mock.calls[0]; - - expect(config.path).toMatchInlineSnapshot(`"/api/action/_find"`); - expect(config.options).toMatchInlineSnapshot(` - Object { - "tags": Array [ - "access:actions-read", - ], - } - `); - - const findResult = { - page: 1, - perPage: 1, - total: 0, - data: [], - }; - const actionsClient = { - find: jest.fn().mockResolvedValueOnce(findResult), - }; - - const [context, req, res] = mockHandlerArguments( - { actionsClient }, - { - query: { - per_page: 1, - page: 1, - default_search_operator: 'OR', - }, - }, - ['ok'] - ); - - expect(await handler(context, req, res)).toMatchInlineSnapshot(` - Object { - "body": Object { - "data": Array [], - "page": 1, - "perPage": 1, - "total": 0, - }, - } - `); - - expect(actionsClient.find).toHaveBeenCalledTimes(1); - expect(actionsClient.find.mock.calls[0]).toMatchInlineSnapshot(` - Array [ - Object { - "options": Object { - "defaultSearchOperator": "OR", - "fields": undefined, - "filter": undefined, - "page": 1, - "perPage": 1, - "search": undefined, - "sortField": undefined, - "sortOrder": undefined, - }, - }, - ] - `); - - expect(res.ok).toHaveBeenCalledWith({ - body: findResult, - }); - }); - - it('ensures the license allows finding actions', async () => { - const licenseState = licenseStateMock.create(); - const router: RouterMock = mockRouter.create(); - - findActionRoute(router, licenseState); - - const [, handler] = router.get.mock.calls[0]; - - const actionsClient = { - find: jest.fn().mockResolvedValueOnce({ - page: 1, - perPage: 1, - total: 0, - data: [], - }), - }; - - const [context, req, res] = mockHandlerArguments(actionsClient, { - query: { - per_page: 1, - page: 1, - default_search_operator: 'OR', - }, - }); - - await handler(context, req, res); - - expect(verifyApiAccess).toHaveBeenCalledWith(licenseState); - }); - - it('ensures the license check prevents finding actions', async () => { - const licenseState = licenseStateMock.create(); - const router: RouterMock = mockRouter.create(); - - (verifyApiAccess as jest.Mock).mockImplementation(() => { - throw new Error('OMG'); - }); - - findActionRoute(router, licenseState); - - const [, handler] = router.get.mock.calls[0]; - - const [context, req, res] = mockHandlerArguments( - {}, - { - query: { - per_page: 1, - page: 1, - default_search_operator: 'OR', - }, - }, - ['ok'] - ); - expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); - - expect(verifyApiAccess).toHaveBeenCalledWith(licenseState); - }); -}); diff --git a/x-pack/plugins/actions/server/routes/find.ts b/x-pack/plugins/actions/server/routes/find.ts deleted file mode 100644 index 45b967629a2a8..0000000000000 --- a/x-pack/plugins/actions/server/routes/find.ts +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { schema, TypeOf } from '@kbn/config-schema'; -import { - IRouter, - RequestHandlerContext, - KibanaRequest, - IKibanaResponse, - KibanaResponseFactory, -} from 'kibana/server'; -import { FindOptions } from '../../../alerting/server'; -import { ILicenseState, verifyApiAccess } from '../lib'; -import { BASE_ACTION_API_PATH } from '../../common'; - -// config definition -const querySchema = schema.object({ - per_page: schema.number({ defaultValue: 20, min: 0 }), - page: schema.number({ defaultValue: 1, min: 1 }), - search: schema.maybe(schema.string()), - default_search_operator: schema.oneOf([schema.literal('OR'), schema.literal('AND')], { - defaultValue: 'OR', - }), - search_fields: schema.maybe(schema.oneOf([schema.arrayOf(schema.string()), schema.string()])), - sort_field: schema.maybe(schema.string()), - sort_order: schema.maybe(schema.oneOf([schema.literal('asc'), schema.literal('desc')])), - has_reference: schema.maybe( - // use nullable as maybe is currently broken - // in config-schema - schema.nullable( - schema.object({ - type: schema.string(), - id: schema.string(), - }) - ) - ), - fields: schema.maybe(schema.arrayOf(schema.string())), - filter: schema.maybe(schema.string()), -}); - -export const findActionRoute = (router: IRouter, licenseState: ILicenseState) => { - router.get( - { - path: `${BASE_ACTION_API_PATH}/_find`, - validate: { - query: querySchema, - }, - options: { - tags: ['access:actions-read'], - }, - }, - router.handleLegacyErrors(async function( - context: RequestHandlerContext, - req: KibanaRequest, any, any>, - res: KibanaResponseFactory - ): Promise> { - verifyApiAccess(licenseState); - if (!context.actions) { - return res.badRequest({ body: 'RouteHandlerContext is not registered for actions' }); - } - const actionsClient = context.actions.getActionsClient(); - const query = req.query; - const options: FindOptions['options'] = { - perPage: query.per_page, - page: query.page, - search: query.search, - defaultSearchOperator: query.default_search_operator, - sortField: query.sort_field, - fields: query.fields, - filter: query.filter, - sortOrder: query.sort_order, - }; - - if (query.search_fields) { - options.searchFields = Array.isArray(query.search_fields) - ? query.search_fields - : [query.search_fields]; - } - - if (query.has_reference) { - options.hasReference = query.has_reference; - } - - const findResult = await actionsClient.find({ - options, - }); - return res.ok({ - body: findResult, - }); - }) - ); -}; diff --git a/x-pack/plugins/actions/server/routes/get_all.test.ts b/x-pack/plugins/actions/server/routes/get_all.test.ts new file mode 100644 index 0000000000000..6499427b8c1a5 --- /dev/null +++ b/x-pack/plugins/actions/server/routes/get_all.test.ts @@ -0,0 +1,117 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { getAllActionRoute } from './get_all'; +import { mockRouter, RouterMock } from '../../../../../src/core/server/http/router/router.mock'; +import { licenseStateMock } from '../lib/license_state.mock'; +import { verifyApiAccess } from '../lib'; +import { mockHandlerArguments } from './_mock_handler_arguments'; + +jest.mock('../lib/verify_api_access.ts', () => ({ + verifyApiAccess: jest.fn(), +})); + +beforeEach(() => { + jest.resetAllMocks(); +}); + +describe('getAllActionRoute', () => { + it('get all actions with proper parameters', async () => { + const licenseState = licenseStateMock.create(); + const router: RouterMock = mockRouter.create(); + + getAllActionRoute(router, licenseState); + + const [config, handler] = router.get.mock.calls[0]; + + expect(config.path).toMatchInlineSnapshot(`"/api/action/_getAll"`); + expect(config.options).toMatchInlineSnapshot(` + Object { + "tags": Array [ + "access:actions-read", + ], + } + `); + + const actionsClient = { + getAll: jest.fn().mockResolvedValueOnce([]), + }; + + const [context, req, res] = mockHandlerArguments({ actionsClient }, {}, ['ok']); + + expect(await handler(context, req, res)).toMatchInlineSnapshot(` + Object { + "body": Array [], + } + `); + + expect(actionsClient.getAll).toHaveBeenCalledTimes(1); + + expect(res.ok).toHaveBeenCalledWith({ + body: [], + }); + }); + + it('ensures the license allows getting all actions', async () => { + const licenseState = licenseStateMock.create(); + const router: RouterMock = mockRouter.create(); + + getAllActionRoute(router, licenseState); + + const [config, handler] = router.get.mock.calls[0]; + + expect(config.path).toMatchInlineSnapshot(`"/api/action/_getAll"`); + expect(config.options).toMatchInlineSnapshot(` + Object { + "tags": Array [ + "access:actions-read", + ], + } + `); + + const actionsClient = { + getAll: jest.fn().mockResolvedValueOnce([]), + }; + + const [context, req, res] = mockHandlerArguments({ actionsClient }, {}, ['ok']); + + await handler(context, req, res); + + expect(verifyApiAccess).toHaveBeenCalledWith(licenseState); + }); + + it('ensures the license check prevents getting all actions', async () => { + const licenseState = licenseStateMock.create(); + const router: RouterMock = mockRouter.create(); + + (verifyApiAccess as jest.Mock).mockImplementation(() => { + throw new Error('OMG'); + }); + + getAllActionRoute(router, licenseState); + + const [config, handler] = router.get.mock.calls[0]; + + expect(config.path).toMatchInlineSnapshot(`"/api/action/_getAll"`); + expect(config.options).toMatchInlineSnapshot(` + Object { + "tags": Array [ + "access:actions-read", + ], + } + `); + + const actionsClient = { + getAll: jest.fn().mockResolvedValueOnce([]), + }; + + const [context, req, res] = mockHandlerArguments({ actionsClient }, {}, ['ok']); + + expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); + + expect(verifyApiAccess).toHaveBeenCalledWith(licenseState); + }); +}); diff --git a/x-pack/plugins/actions/server/routes/get_all.ts b/x-pack/plugins/actions/server/routes/get_all.ts new file mode 100644 index 0000000000000..c70a13bc01c9f --- /dev/null +++ b/x-pack/plugins/actions/server/routes/get_all.ts @@ -0,0 +1,42 @@ +/* + * 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 { + IRouter, + RequestHandlerContext, + KibanaRequest, + IKibanaResponse, + KibanaResponseFactory, +} from 'kibana/server'; +import { ILicenseState, verifyApiAccess } from '../lib'; +import { BASE_ACTION_API_PATH } from '../../common'; + +export const getAllActionRoute = (router: IRouter, licenseState: ILicenseState) => { + router.get( + { + path: `${BASE_ACTION_API_PATH}/_getAll`, + validate: {}, + options: { + tags: ['access:actions-read'], + }, + }, + router.handleLegacyErrors(async function( + context: RequestHandlerContext, + req: KibanaRequest, + res: KibanaResponseFactory + ): Promise> { + verifyApiAccess(licenseState); + if (!context.actions) { + return res.badRequest({ body: 'RouteHandlerContext is not registered for actions' }); + } + const actionsClient = context.actions.getActionsClient(); + const result = await actionsClient.getAll(); + return res.ok({ + body: result, + }); + }) + ); +}; diff --git a/x-pack/plugins/actions/server/routes/index.ts b/x-pack/plugins/actions/server/routes/index.ts index 33191132bece5..94f9ec1c94364 100644 --- a/x-pack/plugins/actions/server/routes/index.ts +++ b/x-pack/plugins/actions/server/routes/index.ts @@ -6,7 +6,7 @@ export { createActionRoute } from './create'; export { deleteActionRoute } from './delete'; -export { findActionRoute } from './find'; +export { getAllActionRoute } from './get_all'; export { getActionRoute } from './get'; export { updateActionRoute } from './update'; export { listActionTypesRoute } from './list_action_types'; diff --git a/x-pack/plugins/actions/server/types.ts b/x-pack/plugins/actions/server/types.ts index 999e739e77060..92e38d77314f8 100644 --- a/x-pack/plugins/actions/server/types.ts +++ b/x-pack/plugins/actions/server/types.ts @@ -55,6 +55,11 @@ export interface ActionResult { actionTypeId: string; name: string; config: Record; + isPreconfigured: boolean; +} + +export interface PreConfiguredAction extends ActionResult { + secrets: Record; } export interface FindActionResult extends ActionResult { diff --git a/x-pack/plugins/alerting/server/alerts_client.test.ts b/x-pack/plugins/alerting/server/alerts_client.test.ts index 0e929ff457fbd..a9ff5ee8ecdc6 100644 --- a/x-pack/plugins/alerting/server/alerts_client.test.ts +++ b/x-pack/plugins/alerting/server/alerts_client.test.ts @@ -30,6 +30,7 @@ const alertsClientParams = { invalidateAPIKey: jest.fn(), logger: loggingServiceMock.create().get(), encryptedSavedObjectsPlugin: encryptedSavedObjects, + preconfiguredActions: [], }; beforeEach(() => { diff --git a/x-pack/plugins/alerting/server/alerts_client.ts b/x-pack/plugins/alerting/server/alerts_client.ts index 5538b44b69fcb..6f8478df58a53 100644 --- a/x-pack/plugins/alerting/server/alerts_client.ts +++ b/x-pack/plugins/alerting/server/alerts_client.ts @@ -13,6 +13,7 @@ import { SavedObjectReference, SavedObject, } from 'src/core/server'; +import { PreConfiguredAction } from '../../actions/server'; import { Alert, PartialAlert, @@ -53,6 +54,7 @@ interface ConstructorOptions { getUserName: () => Promise; createAPIKey: () => Promise; invalidateAPIKey: (params: InvalidateAPIKeyParams) => Promise; + preconfiguredActions: PreConfiguredAction[]; } export interface FindOptions { @@ -123,6 +125,7 @@ export class AlertsClient { private readonly invalidateAPIKey: ( params: InvalidateAPIKeyParams ) => Promise; + private preconfiguredActions: PreConfiguredAction[]; encryptedSavedObjectsPlugin: EncryptedSavedObjectsPluginStart; constructor({ @@ -136,6 +139,7 @@ export class AlertsClient { createAPIKey, invalidateAPIKey, encryptedSavedObjectsPlugin, + preconfiguredActions, }: ConstructorOptions) { this.logger = logger; this.getUserName = getUserName; @@ -147,6 +151,7 @@ export class AlertsClient { this.createAPIKey = createAPIKey; this.invalidateAPIKey = invalidateAPIKey; this.encryptedSavedObjectsPlugin = encryptedSavedObjectsPlugin; + this.preconfiguredActions = preconfiguredActions; } public async create({ data, options }: CreateOptions): Promise { @@ -659,18 +664,37 @@ export class AlertsClient { private async denormalizeActions( alertActions: NormalizedAlertAction[] ): Promise<{ actions: RawAlert['actions']; references: SavedObjectReference[] }> { - // Fetch action objects in bulk - const actionIds = [...new Set(alertActions.map(alertAction => alertAction.id))]; - const bulkGetOpts = actionIds.map(id => ({ id, type: 'action' })); - const bulkGetResult = await this.savedObjectsClient.bulkGet(bulkGetOpts); const actionMap = new Map(); - for (const action of bulkGetResult.saved_objects) { - if (action.error) { - throw Boom.badRequest( - `Failed to load action ${action.id} (${action.error.statusCode}): ${action.error.message}` - ); + // map preconfigured actions + for (const alertAction of alertActions) { + const action = this.preconfiguredActions.find( + preconfiguredAction => preconfiguredAction.id === alertAction.id + ); + if (action !== undefined) { + actionMap.set(action.id, action); + } + } + // Fetch action objects in bulk + // Excluding preconfigured actions to avoid an not found error, which is already mapped + const actionIds = [ + ...new Set( + alertActions + .filter(alertAction => !actionMap.has(alertAction.id)) + .map(alertAction => alertAction.id) + ), + ]; + if (actionIds.length > 0) { + const bulkGetOpts = actionIds.map(id => ({ id, type: 'action' })); + const bulkGetResult = await this.savedObjectsClient.bulkGet(bulkGetOpts); + + for (const action of bulkGetResult.saved_objects) { + if (action.error) { + throw Boom.badRequest( + `Failed to load action ${action.id} (${action.error.statusCode}): ${action.error.message}` + ); + } + actionMap.set(action.id, action); } - actionMap.set(action.id, action); } // Extract references and set actionTypeId const references: SavedObjectReference[] = []; @@ -681,10 +705,16 @@ export class AlertsClient { name: actionRef, type: 'action', }); + const actionMapValue = actionMap.get(id); + // if action is a save object, than actionTypeId should be under attributes property + // if action is a preconfigured, than actionTypeId is the action property + const actionTypeId = actionIds.find(actionId => actionId === id) + ? actionMapValue.attributes.actionTypeId + : actionMapValue.actionTypeId; return { ...alertAction, actionRef, - actionTypeId: actionMap.get(id).attributes.actionTypeId, + actionTypeId, }; }); return { diff --git a/x-pack/plugins/alerting/server/alerts_client_factory.test.ts b/x-pack/plugins/alerting/server/alerts_client_factory.test.ts index 4c74ca54a0d2f..951d18a33b35f 100644 --- a/x-pack/plugins/alerting/server/alerts_client_factory.test.ts +++ b/x-pack/plugins/alerting/server/alerts_client_factory.test.ts @@ -28,6 +28,7 @@ const alertsClientFactoryParams: jest.Mocked = { getSpaceId: jest.fn(), spaceIdToNamespace: jest.fn(), encryptedSavedObjectsPlugin: encryptedSavedObjectsMock.createStart(), + preconfiguredActions: [], }; const fakeRequest: Request = { headers: {}, @@ -67,6 +68,7 @@ test('creates an alerts client with proper constructor arguments', async () => { createAPIKey: expect.any(Function), invalidateAPIKey: expect.any(Function), encryptedSavedObjectsPlugin: alertsClientFactoryParams.encryptedSavedObjectsPlugin, + preconfiguredActions: [], }); }); diff --git a/x-pack/plugins/alerting/server/alerts_client_factory.ts b/x-pack/plugins/alerting/server/alerts_client_factory.ts index fd480658e236a..734417e72733e 100644 --- a/x-pack/plugins/alerting/server/alerts_client_factory.ts +++ b/x-pack/plugins/alerting/server/alerts_client_factory.ts @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ +import { PreConfiguredAction } from '../../actions/server'; import { AlertsClient } from './alerts_client'; import { AlertTypeRegistry, SpaceIdToNamespaceFunction } from './types'; import { KibanaRequest, Logger, SavedObjectsClientContract } from '../../../../src/core/server'; @@ -19,6 +20,7 @@ export interface AlertsClientFactoryOpts { getSpaceId: (request: KibanaRequest) => string | undefined; spaceIdToNamespace: SpaceIdToNamespaceFunction; encryptedSavedObjectsPlugin: EncryptedSavedObjectsPluginStart; + preconfiguredActions: PreConfiguredAction[]; } export class AlertsClientFactory { @@ -30,6 +32,7 @@ export class AlertsClientFactory { private getSpaceId!: (request: KibanaRequest) => string | undefined; private spaceIdToNamespace!: SpaceIdToNamespaceFunction; private encryptedSavedObjectsPlugin!: EncryptedSavedObjectsPluginStart; + private preconfiguredActions!: PreConfiguredAction[]; public initialize(options: AlertsClientFactoryOpts) { if (this.isInitialized) { @@ -43,6 +46,7 @@ export class AlertsClientFactory { this.securityPluginSetup = options.securityPluginSetup; this.spaceIdToNamespace = options.spaceIdToNamespace; this.encryptedSavedObjectsPlugin = options.encryptedSavedObjectsPlugin; + this.preconfiguredActions = options.preconfiguredActions; } public create( @@ -100,6 +104,7 @@ export class AlertsClientFactory { result: invalidateAPIKeyResult, }; }, + preconfiguredActions: this.preconfiguredActions, }); } } diff --git a/x-pack/plugins/alerting/server/plugin.ts b/x-pack/plugins/alerting/server/plugin.ts index 90e274df3a5ee..172a106226345 100644 --- a/x-pack/plugins/alerting/server/plugin.ts +++ b/x-pack/plugins/alerting/server/plugin.ts @@ -218,6 +218,7 @@ export class AlertingPlugin { getSpaceId(request: KibanaRequest) { return spaces?.getSpaceId(request); }, + preconfiguredActions: plugins.actions.preconfiguredActions, }); taskRunnerFactory.initialize({ diff --git a/x-pack/plugins/case/common/api/cases/configure.ts b/x-pack/plugins/case/common/api/cases/configure.ts index 9b210c2aa05ad..d92af587d0e92 100644 --- a/x-pack/plugins/case/common/api/cases/configure.ts +++ b/x-pack/plugins/case/common/api/cases/configure.ts @@ -61,13 +61,6 @@ export type CasesConnectorConfiguration = rt.TypeOf action.actionTypeId === CASE_SERVICE_NOW_ACTION + ); + return response.ok({ body: results }); } catch (error) { return response.customError(wrapError(error)); } diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/email.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/email.test.tsx index a7d479f922ed1..af9e34071fd09 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/email.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/email.test.tsx @@ -39,6 +39,7 @@ describe('connector validation', () => { id: 'test', actionTypeId: '.email', name: 'email', + isPreconfigured: false, config: { from: 'test@test.com', port: 2323, @@ -66,6 +67,7 @@ describe('connector validation', () => { }, id: 'test', actionTypeId: '.email', + isPreconfigured: false, name: 'email', config: { from: 'test@test.com', @@ -117,6 +119,7 @@ describe('connector validation', () => { }, id: 'test', actionTypeId: '.email', + isPreconfigured: false, name: 'email', config: { from: 'test@test.com', @@ -144,6 +147,7 @@ describe('connector validation', () => { }, id: 'test', actionTypeId: '.email', + isPreconfigured: false, name: 'email', config: { from: 'test@test.com', diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook.test.tsx index fdb60bd2d9146..c4489a316d2c0 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook.test.tsx @@ -39,6 +39,7 @@ describe('webhook connector validation', () => { id: 'test', actionTypeId: '.webhook', name: 'webhook', + isPreconfigured: false, config: { method: 'PUT', url: 'http:\\test', @@ -106,6 +107,7 @@ describe('WebhookActionConnectorFields renders', () => { }, id: 'test', actionTypeId: '.webhook', + isPreconfigured: false, name: 'webhook', config: { method: 'PUT', diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api.test.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api.test.ts index ee68b7e269c34..e9cf2a270d180 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api.test.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api.test.ts @@ -43,27 +43,14 @@ describe('loadActionTypes', () => { }); describe('loadAllActions', () => { - test('should call find actions API', async () => { - const resolvedValue = { - page: 1, - perPage: 10000, - total: 0, - data: [], - }; - http.get.mockResolvedValueOnce(resolvedValue); + test('should call getAll actions API', async () => { + http.get.mockResolvedValueOnce([]); const result = await loadAllActions({ http }); - expect(result).toEqual(resolvedValue); + expect(result).toEqual([]); expect(http.get.mock.calls[0]).toMatchInlineSnapshot(` Array [ - "/api/action/_find", - Object { - "query": Object { - "per_page": 10000, - "sort_field": "name.keyword", - "sort_order": "asc", - }, - }, + "/api/action/_getAll", ] `); }); @@ -73,6 +60,7 @@ describe('createActionConnector', () => { test('should call create action API', async () => { const connector: ActionConnectorWithoutId = { actionTypeId: 'test', + isPreconfigured: false, name: 'My test', config: {}, secrets: {}, @@ -86,7 +74,7 @@ describe('createActionConnector', () => { Array [ "/api/action", Object { - "body": "{\\"actionTypeId\\":\\"test\\",\\"name\\":\\"My test\\",\\"config\\":{},\\"secrets\\":{}}", + "body": "{\\"actionTypeId\\":\\"test\\",\\"isPreconfigured\\":false,\\"name\\":\\"My test\\",\\"config\\":{},\\"secrets\\":{}}", }, ] `); @@ -98,6 +86,7 @@ describe('updateActionConnector', () => { const id = '123'; const connector: ActionConnectorWithoutId = { actionTypeId: 'test', + isPreconfigured: false, name: 'My test', config: {}, secrets: {}, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api.ts index 26ad97f05849d..e82d268accdd8 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api.ts @@ -8,32 +8,12 @@ import { HttpSetup } from 'kibana/public'; import { BASE_ACTION_API_PATH } from '../constants'; import { ActionConnector, ActionConnectorWithoutId, ActionType } from '../../types'; -// We are assuming there won't be many actions. This is why we will load -// all the actions in advance and assume the total count to not go over 100 or so. -// We'll set this max setting assuming it's never reached. -const MAX_ACTIONS_RETURNED = 10000; - export async function loadActionTypes({ http }: { http: HttpSetup }): Promise { return await http.get(`${BASE_ACTION_API_PATH}/types`); } -export async function loadAllActions({ - http, -}: { - http: HttpSetup; -}): Promise<{ - page: number; - perPage: number; - total: number; - data: ActionConnector[]; -}> { - return await http.get(`${BASE_ACTION_API_PATH}/_find`, { - query: { - per_page: MAX_ACTIONS_RETURNED, - sort_field: 'name.keyword', - sort_order: 'asc', - }, - }); +export async function loadAllActions({ http }: { http: HttpSetup }): Promise { + return await http.get(`${BASE_ACTION_API_PATH}/_getAll`); } export async function createActionConnector({ diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx index 89d37c4d00a11..41564146bb84d 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx @@ -11,6 +11,10 @@ import { act } from 'react-dom/test-utils'; import { actionTypeRegistryMock } from '../../action_type_registry.mock'; import { ValidationResult, Alert, AlertAction } from '../../../types'; import { ActionForm } from './action_form'; +jest.mock('../../lib/action_connector_api', () => ({ + loadAllActions: jest.fn(), + loadActionTypes: jest.fn(), +})); const actionTypeRegistry = actionTypeRegistryMock.create(); describe('action_form', () => { let deps: any; @@ -73,6 +77,17 @@ describe('action_form', () => { let wrapper: ReactWrapper; async function setup() { + const { loadAllActions } = jest.requireMock('../../lib/action_connector_api'); + loadAllActions.mockResolvedValueOnce([ + { + secrets: {}, + id: 'test', + actionTypeId: actionType.id, + name: 'Test connector', + config: {}, + isPreconfigured: false, + }, + ]); const mockes = coreMock.createSetup(); deps = { toastNotifications: mockes.notifications.toasts, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx index 3ade4e6368f96..6b011ac84bc6f 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx @@ -129,7 +129,7 @@ export const ActionForm = ({ async function loadConnectors() { try { const actionsResponse = await loadAllActions({ http }); - setConnectors(actionsResponse.data); + setConnectors(actionsResponse); } catch (e) { toastNotifications.addDanger({ title: i18n.translate( diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_edit_flyout.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_edit_flyout.test.tsx index f9aa2cad8bfc6..2c063ea6b4fa6 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_edit_flyout.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_edit_flyout.test.tsx @@ -47,6 +47,7 @@ describe('connector_edit_flyout', () => { actionTypeId: 'test-action-type-id', actionType: 'test-action-type-name', name: 'action-connector', + isPreconfigured: false, referencedByCount: 0, config: {}, }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_reducer.test.ts b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_reducer.test.ts index df7e5d8fe9a78..e469a50108912 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_reducer.test.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_reducer.test.ts @@ -15,6 +15,7 @@ describe('connector reducer', () => { actionTypeId: 'test-action-type-id', name: 'action-connector', referencedByCount: 0, + isPreconfigured: false, config: {}, }; }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.test.tsx index 9331fe1704694..4fa1e7e4c6e4d 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.test.tsx @@ -29,12 +29,7 @@ describe('actions_connectors_list component empty', () => { const { loadAllActions, loadActionTypes } = jest.requireMock( '../../../lib/action_connector_api' ); - loadAllActions.mockResolvedValueOnce({ - page: 1, - perPage: 10000, - total: 0, - data: [], - }); + loadAllActions.mockResolvedValueOnce([]); loadActionTypes.mockResolvedValueOnce([ { id: 'test', @@ -111,27 +106,22 @@ describe('actions_connectors_list component with items', () => { const { loadAllActions, loadActionTypes } = jest.requireMock( '../../../lib/action_connector_api' ); - loadAllActions.mockResolvedValueOnce({ - page: 1, - perPage: 10000, - total: 2, - data: [ - { - id: '1', - actionTypeId: 'test', - description: 'My test', - referencedByCount: 1, - config: {}, - }, - { - id: '2', - actionTypeId: 'test2', - description: 'My test 2', - referencedByCount: 1, - config: {}, - }, - ], - }); + loadAllActions.mockResolvedValueOnce([ + { + id: '1', + actionTypeId: 'test', + description: 'My test', + referencedByCount: 1, + config: {}, + }, + { + id: '2', + actionTypeId: 'test2', + description: 'My test 2', + referencedByCount: 1, + config: {}, + }, + ]); loadActionTypes.mockResolvedValueOnce([ { id: 'test', @@ -214,12 +204,7 @@ describe('actions_connectors_list component empty with show only capability', () const { loadAllActions, loadActionTypes } = jest.requireMock( '../../../lib/action_connector_api' ); - loadAllActions.mockResolvedValueOnce({ - page: 1, - perPage: 10000, - total: 0, - data: [], - }); + loadAllActions.mockResolvedValueOnce([]); loadActionTypes.mockResolvedValueOnce([ { id: 'test', @@ -289,27 +274,22 @@ describe('actions_connectors_list with show only capability', () => { const { loadAllActions, loadActionTypes } = jest.requireMock( '../../../lib/action_connector_api' ); - loadAllActions.mockResolvedValueOnce({ - page: 1, - perPage: 10000, - total: 2, - data: [ - { - id: '1', - actionTypeId: 'test', - description: 'My test', - referencedByCount: 1, - config: {}, - }, - { - id: '2', - actionTypeId: 'test2', - description: 'My test 2', - referencedByCount: 1, - config: {}, - }, - ], - }); + loadAllActions.mockResolvedValueOnce([ + { + id: '1', + actionTypeId: 'test', + description: 'My test', + referencedByCount: 1, + config: {}, + }, + { + id: '2', + actionTypeId: 'test2', + description: 'My test 2', + referencedByCount: 1, + config: {}, + }, + ]); loadActionTypes.mockResolvedValueOnce([ { id: 'test', @@ -384,27 +364,22 @@ describe('actions_connectors_list component with disabled items', () => { const { loadAllActions, loadActionTypes } = jest.requireMock( '../../../lib/action_connector_api' ); - loadAllActions.mockResolvedValueOnce({ - page: 1, - perPage: 10000, - total: 2, - data: [ - { - id: '1', - actionTypeId: 'test', - description: 'My test', - referencedByCount: 1, - config: {}, - }, - { - id: '2', - actionTypeId: 'test2', - description: 'My test 2', - referencedByCount: 1, - config: {}, - }, - ], - }); + loadAllActions.mockResolvedValueOnce([ + { + id: '1', + actionTypeId: 'test', + description: 'My test', + referencedByCount: 1, + config: {}, + }, + { + id: '2', + actionTypeId: 'test2', + description: 'My test 2', + referencedByCount: 1, + config: {}, + }, + ]); loadActionTypes.mockResolvedValueOnce([ { id: 'test', diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.tsx index fc07171347e5e..81693e1d2d9d1 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.tsx @@ -110,7 +110,7 @@ export const ActionsConnectorsList: React.FunctionComponent = () => { setIsLoadingActions(true); try { const actionsResponse = await loadAllActions({ http }); - setActions(actionsResponse.data); + setActions(actionsResponse); } catch (e) { toastNotifications.addDanger({ title: i18n.translate( diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.test.tsx index 108cc724aa407..66aa02e1930a3 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.test.tsx @@ -72,12 +72,7 @@ describe('alerts_list component empty', () => { }, ]); loadAlertTypes.mockResolvedValue([{ id: 'test_alert_type', name: 'some alert type' }]); - loadAllActions.mockResolvedValue({ - page: 1, - perPage: 10000, - total: 0, - data: [], - }); + loadAllActions.mockResolvedValue([]); const mockes = coreMock.createSetup(); const [ @@ -196,12 +191,7 @@ describe('alerts_list component with items', () => { }, ]); loadAlertTypes.mockResolvedValue([{ id: 'test_alert_type', name: 'some alert type' }]); - loadAllActions.mockResolvedValue({ - page: 1, - perPage: 10000, - total: 0, - data: [], - }); + loadAllActions.mockResolvedValue([]); const mockes = coreMock.createSetup(); const [ { @@ -286,12 +276,7 @@ describe('alerts_list component empty with show only capability', () => { }, ]); loadAlertTypes.mockResolvedValue([{ id: 'test_alert_type', name: 'some alert type' }]); - loadAllActions.mockResolvedValue({ - page: 1, - perPage: 10000, - total: 0, - data: [], - }); + loadAllActions.mockResolvedValue([]); const mockes = coreMock.createSetup(); const [ { @@ -405,12 +390,7 @@ describe('alerts_list with show only capability', () => { }, ]); loadAlertTypes.mockResolvedValue([{ id: 'test_alert_type', name: 'some alert type' }]); - loadAllActions.mockResolvedValue({ - page: 1, - perPage: 10000, - total: 0, - data: [], - }); + loadAllActions.mockResolvedValue([]); const mockes = coreMock.createSetup(); const [ { diff --git a/x-pack/plugins/triggers_actions_ui/public/types.ts b/x-pack/plugins/triggers_actions_ui/public/types.ts index 7dfaa7b918f70..31c77833cc0e8 100644 --- a/x-pack/plugins/triggers_actions_ui/public/types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/types.ts @@ -66,6 +66,7 @@ export interface ActionConnector { name: string; referencedByCount?: number; config: Record; + isPreconfigured: boolean; } export type ActionConnectorWithoutId = Omit; diff --git a/x-pack/test/alerting_api_integration/common/config.ts b/x-pack/test/alerting_api_integration/common/config.ts index 5fb1afa7d584f..4d32a5ae9f53c 100644 --- a/x-pack/test/alerting_api_integration/common/config.ts +++ b/x-pack/test/alerting_api_integration/common/config.ts @@ -77,6 +77,30 @@ export function createTestConfig(name: string, options: CreateTestConfigOptions) `--xpack.actions.enabledActionTypes=${JSON.stringify(enabledActionTypes)}`, '--xpack.alerting.enabled=true', '--xpack.eventLog.logEntries=true', + `--xpack.actions.preconfigured=${JSON.stringify([ + { + id: 'my-slack1', + actionTypeId: '.slack', + name: 'Slack#xyz', + config: { + webhookUrl: 'https://hooks.slack.com/services/abcd/efgh/ijklmnopqrstuvwxyz', + }, + }, + { + id: 'custom-system-abc-connector', + actionTypeId: 'system-abc-action-type', + name: 'SystemABC', + config: { + xyzConfig1: 'value1', + xyzConfig2: 'value2', + listOfThings: ['a', 'b', 'c', 'd'], + }, + secrets: { + xyzSecret1: 'credential1', + xyzSecret2: 'credential2', + }, + }, + ])}`, ...disabledPlugins.map(key => `--xpack.${key}.enabled=false`), `--plugin-path=${path.join(__dirname, 'fixtures', 'plugins', 'alerts')}`, `--plugin-path=${path.join(__dirname, 'fixtures', 'plugins', 'actions')}`, diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/email.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/email.ts index e228f6c1f81c6..6001dd531cfae 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/email.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/email.ts @@ -39,6 +39,7 @@ export default function emailTest({ getService }: FtrProviderContext) { createdActionId = createdAction.id; expect(createdAction).to.eql({ id: createdActionId, + isPreconfigured: false, name: 'An email action', actionTypeId: '.email', config: { @@ -58,6 +59,7 @@ export default function emailTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, + isPreconfigured: false, name: 'An email action', actionTypeId: '.email', config: { diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/es_index.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/es_index.ts index 01eaf92da33fe..612eba858ea0b 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/es_index.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/es_index.ts @@ -40,6 +40,7 @@ export default function indexTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdAction.id, + isPreconfigured: false, name: 'An index action', actionTypeId: '.index', config: { @@ -57,6 +58,7 @@ export default function indexTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, + isPreconfigured: false, name: 'An index action', actionTypeId: '.index', config: { index: ES_TEST_INDEX_NAME, refresh: false, executionTimeField: null }, @@ -79,6 +81,7 @@ export default function indexTest({ getService }: FtrProviderContext) { expect(createdActionWithIndex).to.eql({ id: createdActionWithIndex.id, + isPreconfigured: false, name: 'An index action with index config', actionTypeId: '.index', config: { @@ -96,6 +99,7 @@ export default function indexTest({ getService }: FtrProviderContext) { expect(fetchedActionWithIndex).to.eql({ id: fetchedActionWithIndex.id, + isPreconfigured: false, name: 'An index action with index config', actionTypeId: '.index', config: { diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/pagerduty.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/pagerduty.ts index cfc04663c6a4f..eeb0818b5fbab 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/pagerduty.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/pagerduty.ts @@ -50,6 +50,7 @@ export default function pagerdutyTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdAction.id, + isPreconfigured: false, name: 'A pagerduty action', actionTypeId: '.pagerduty', config: { @@ -65,6 +66,7 @@ export default function pagerdutyTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, + isPreconfigured: false, name: 'A pagerduty action', actionTypeId: '.pagerduty', config: { diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/server_log.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/server_log.ts index f4ea568cf08c3..e9d3e6c542442 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/server_log.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/server_log.ts @@ -31,6 +31,7 @@ export default function serverLogTest({ getService }: FtrProviderContext) { serverLogActionId = createdAction.id; expect(createdAction).to.eql({ id: createdAction.id, + isPreconfigured: false, name: 'A server.log action', actionTypeId: '.server-log', config: {}, @@ -44,6 +45,7 @@ export default function serverLogTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, + isPreconfigured: false, name: 'A server.log action', actionTypeId: '.server-log', config: {}, diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow.ts index 48f348e1b834d..054f8f6141817 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow.ts @@ -101,6 +101,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdAction.id, + isPreconfigured: false, name: 'A servicenow action', actionTypeId: '.servicenow', config: { @@ -117,6 +118,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, + isPreconfigured: false, name: 'A servicenow action', actionTypeId: '.servicenow', config: { diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/slack.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/slack.ts index 8afa43bfea21e..e00589b7e85b7 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/slack.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/slack.ts @@ -47,6 +47,7 @@ export default function slackTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdAction.id, + isPreconfigured: false, name: 'A slack action', actionTypeId: '.slack', config: {}, @@ -60,6 +61,7 @@ export default function slackTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, + isPreconfigured: false, name: 'A slack action', actionTypeId: '.slack', config: {}, diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/webhook.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/webhook.ts index da83dbf8c47e2..fd996ea4507ba 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/webhook.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/webhook.ts @@ -92,6 +92,7 @@ export default function webhookTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdAction.id, + isPreconfigured: false, name: 'A generic Webhook action', actionTypeId: '.webhook', config: { @@ -108,6 +109,7 @@ export default function webhookTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, + isPreconfigured: false, name: 'A generic Webhook action', actionTypeId: '.webhook', config: { diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/create.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/create.ts index 43a3861491467..922315eba5a5c 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/create.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/create.ts @@ -55,6 +55,7 @@ export default function createActionTests({ getService }: FtrProviderContext) { objectRemover.add(space.id, response.body.id, 'action'); expect(response.body).to.eql({ id: response.body.id, + isPreconfigured: false, name: 'My action', actionTypeId: 'test.index-record', config: { diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/delete.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/delete.ts index 6fca330887c3e..011e47cf11b39 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/delete.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/delete.ts @@ -137,6 +137,36 @@ export default function deleteActionTests({ getService }: FtrProviderContext) { throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`); } }); + + it(`shouldn't delete action from preconfigured list`, async () => { + const response = await supertestWithoutAuth + .delete(`${getUrlPrefix(space.id)}/api/action/my-slack1`) + .auth(user.username, user.password) + .set('kbn-xsrf', 'foo'); + + switch (scenario.id) { + case 'no_kibana_privileges at space1': + case 'global_read at space1': + case 'space_1_all at space2': + expect(response.statusCode).to.eql(404); + expect(response.body).to.eql({ + statusCode: 404, + error: 'Not Found', + message: 'Not Found', + }); + break; + case 'superuser at space1': + case 'space_1_all at space1': + expect(response.body).to.eql({ + statusCode: 400, + error: 'Bad Request', + message: 'Preconfigured action my-slack1 is not allowed to delete.', + }); + break; + default: + throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`); + } + }); }); } }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/get.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/get.ts index bed4c805aaf57..c84b089d48c85 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/get.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/get.ts @@ -59,6 +59,7 @@ export default function getActionTests({ getService }: FtrProviderContext) { expect(response.statusCode).to.eql(200); expect(response.body).to.eql({ id: createdAction.id, + isPreconfigured: false, actionTypeId: 'test.index-record', name: 'My action', config: { @@ -115,6 +116,40 @@ export default function getActionTests({ getService }: FtrProviderContext) { throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`); } }); + + it('should handle get preconfigured action request appropriately', async () => { + const response = await supertestWithoutAuth + .get(`${getUrlPrefix(space.id)}/api/action/my-slack1`) + .auth(user.username, user.password); + + switch (scenario.id) { + case 'no_kibana_privileges at space1': + case 'space_1_all at space2': + expect(response.statusCode).to.eql(404); + expect(response.body).to.eql({ + statusCode: 404, + error: 'Not Found', + message: 'Not Found', + }); + break; + case 'global_read at space1': + case 'superuser at space1': + case 'space_1_all at space1': + expect(response.statusCode).to.eql(200); + expect(response.body).to.eql({ + id: 'my-slack1', + actionTypeId: '.slack', + name: 'Slack#xyz', + isPreconfigured: true, + config: { + webhookUrl: 'https://hooks.slack.com/services/abcd/efgh/ijklmnopqrstuvwxyz', + }, + }); + break; + default: + throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`); + } + }); }); } }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/find.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/get_all.ts similarity index 57% rename from x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/find.ts rename to x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/get_all.ts index 89c5b4f451f82..80b512f3fb5e3 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/find.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/get_all.ts @@ -10,11 +10,11 @@ import { getUrlPrefix, getTestAlertData, ObjectRemover } from '../../../common/l import { FtrProviderContext } from '../../../common/ftr_provider_context'; // eslint-disable-next-line import/no-default-export -export default function findActionTests({ getService }: FtrProviderContext) { +export default function getAllActionTests({ getService }: FtrProviderContext) { const supertest = getService('supertest'); const supertestWithoutAuth = getService('supertestWithoutAuth'); - describe('find', () => { + describe('getAll', () => { const objectRemover = new ObjectRemover(supertest); afterEach(() => objectRemover.removeAll()); @@ -22,7 +22,7 @@ export default function findActionTests({ getService }: FtrProviderContext) { for (const scenario of UserAtSpaceScenarios) { const { user, space } = scenario; describe(scenario.id, () => { - it('should handle find action request appropriately', async () => { + it('should handle get all action request appropriately', async () => { const { body: createdAction } = await supertest .post(`${getUrlPrefix(space.id)}/api/action`) .set('kbn-xsrf', 'foo') @@ -40,11 +40,7 @@ export default function findActionTests({ getService }: FtrProviderContext) { objectRemover.add(space.id, createdAction.id, 'action'); const response = await supertestWithoutAuth - .get( - `${getUrlPrefix( - space.id - )}/api/action/_find?search=test.index-record&search_fields=actionTypeId` - ) + .get(`${getUrlPrefix(space.id)}/api/action/_getAll`) .auth(user.username, user.password); switch (scenario.id) { @@ -61,90 +57,47 @@ export default function findActionTests({ getService }: FtrProviderContext) { case 'superuser at space1': case 'space_1_all at space1': expect(response.statusCode).to.eql(200); - expect(response.body).to.eql({ - page: 1, - perPage: 20, - total: 1, - data: [ - { - id: createdAction.id, - name: 'My action', - actionTypeId: 'test.index-record', - config: { - unencrypted: `This value shouldn't get encrypted`, - }, - referencedByCount: 0, + expect(response.body).to.eql([ + { + id: createdAction.id, + isPreconfigured: false, + name: 'My action', + actionTypeId: 'test.index-record', + config: { + unencrypted: `This value shouldn't get encrypted`, }, - ], - }); - break; - default: - throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`); - } - }); - - it('should handle find action request with filter appropriately', async () => { - const { body: createdAction } = await supertest - .post(`${getUrlPrefix(space.id)}/api/action`) - .set('kbn-xsrf', 'foo') - .send({ - name: 'My action', - actionTypeId: 'test.index-record', - config: { - unencrypted: `This value shouldn't get encrypted`, - }, - secrets: { - encrypted: 'This value should be encrypted', - }, - }) - .expect(200); - objectRemover.add(space.id, createdAction.id, 'action'); - - const response = await supertestWithoutAuth - .get( - `${getUrlPrefix( - space.id - )}/api/action/_find?filter=action.attributes.actionTypeId:test.index-record` - ) - .auth(user.username, user.password); - - switch (scenario.id) { - case 'no_kibana_privileges at space1': - case 'space_1_all at space2': - expect(response.statusCode).to.eql(404); - expect(response.body).to.eql({ - statusCode: 404, - error: 'Not Found', - message: 'Not Found', - }); - break; - case 'global_read at space1': - case 'superuser at space1': - case 'space_1_all at space1': - expect(response.statusCode).to.eql(200); - expect(response.body).to.eql({ - page: 1, - perPage: 20, - total: 1, - data: [ - { - id: createdAction.id, - name: 'My action', - actionTypeId: 'test.index-record', - config: { - unencrypted: `This value shouldn't get encrypted`, - }, - referencedByCount: 0, + referencedByCount: 0, + }, + { + id: 'my-slack1', + isPreconfigured: true, + actionTypeId: '.slack', + name: 'Slack#xyz', + config: { + webhookUrl: 'https://hooks.slack.com/services/abcd/efgh/ijklmnopqrstuvwxyz', }, - ], - }); + referencedByCount: 0, + }, + { + id: 'custom-system-abc-connector', + isPreconfigured: true, + actionTypeId: 'system-abc-action-type', + name: 'SystemABC', + config: { + xyzConfig1: 'value1', + xyzConfig2: 'value2', + listOfThings: ['a', 'b', 'c', 'd'], + }, + referencedByCount: 0, + }, + ]); break; default: throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`); } }); - it('should handle find request appropriately with proper referencedByCount', async () => { + it('should handle get all request appropriately with proper referencedByCount', async () => { const { body: createdAction } = await supertest .post(`${getUrlPrefix(space.id)}/api/action`) .set('kbn-xsrf', 'foo') @@ -172,6 +125,13 @@ export default function findActionTests({ getService }: FtrProviderContext) { id: createdAction.id, params: {}, }, + { + group: 'default', + id: 'my-slack1', + params: { + message: 'test', + }, + }, ], }) ) @@ -179,11 +139,7 @@ export default function findActionTests({ getService }: FtrProviderContext) { objectRemover.add(space.id, createdAlert.id, 'alert'); const response = await supertestWithoutAuth - .get( - `${getUrlPrefix( - space.id - )}/api/action/_find?filter=action.attributes.actionTypeId:test.index-record` - ) + .get(`${getUrlPrefix(space.id)}/api/action/_getAll`) .auth(user.username, user.password); switch (scenario.id) { @@ -200,29 +156,47 @@ export default function findActionTests({ getService }: FtrProviderContext) { case 'superuser at space1': case 'space_1_all at space1': expect(response.statusCode).to.eql(200); - expect(response.body).to.eql({ - page: 1, - perPage: 20, - total: 1, - data: [ - { - id: createdAction.id, - name: 'My action', - actionTypeId: 'test.index-record', - config: { - unencrypted: `This value shouldn't get encrypted`, - }, - referencedByCount: 1, + expect(response.body).to.eql([ + { + id: createdAction.id, + isPreconfigured: false, + name: 'My action', + actionTypeId: 'test.index-record', + config: { + unencrypted: `This value shouldn't get encrypted`, }, - ], - }); + referencedByCount: 1, + }, + { + id: 'my-slack1', + isPreconfigured: true, + actionTypeId: '.slack', + name: 'Slack#xyz', + config: { + webhookUrl: 'https://hooks.slack.com/services/abcd/efgh/ijklmnopqrstuvwxyz', + }, + referencedByCount: 1, + }, + { + id: 'custom-system-abc-connector', + isPreconfigured: true, + actionTypeId: 'system-abc-action-type', + name: 'SystemABC', + config: { + xyzConfig1: 'value1', + xyzConfig2: 'value2', + listOfThings: ['a', 'b', 'c', 'd'], + }, + referencedByCount: 0, + }, + ]); break; default: throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`); } }); - it(`shouldn't find action from another space`, async () => { + it(`shouldn't get actions from another space`, async () => { const { body: createdAction } = await supertest .post(`${getUrlPrefix(space.id)}/api/action`) .set('kbn-xsrf', 'foo') @@ -240,11 +214,7 @@ export default function findActionTests({ getService }: FtrProviderContext) { objectRemover.add(space.id, createdAction.id, 'action'); const response = await supertestWithoutAuth - .get( - `${getUrlPrefix( - 'other' - )}/api/action/_find?search=test.index-record&search_fields=actionTypeId` - ) + .get(`${getUrlPrefix('other')}/api/action/_getAll`) .auth(user.username, user.password); switch (scenario.id) { @@ -261,12 +231,30 @@ export default function findActionTests({ getService }: FtrProviderContext) { case 'global_read at space1': case 'superuser at space1': expect(response.statusCode).to.eql(200); - expect(response.body).to.eql({ - page: 1, - perPage: 20, - total: 0, - data: [], - }); + expect(response.body).to.eql([ + { + id: 'my-slack1', + isPreconfigured: true, + actionTypeId: '.slack', + name: 'Slack#xyz', + config: { + webhookUrl: 'https://hooks.slack.com/services/abcd/efgh/ijklmnopqrstuvwxyz', + }, + referencedByCount: 0, + }, + { + id: 'custom-system-abc-connector', + isPreconfigured: true, + actionTypeId: 'system-abc-action-type', + name: 'SystemABC', + config: { + xyzConfig1: 'value1', + xyzConfig2: 'value2', + listOfThings: ['a', 'b', 'c', 'd'], + }, + referencedByCount: 0, + }, + ]); break; default: throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/index.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/index.ts index c6960a4eedd25..d7ec2e78ccb30 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/index.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/index.ts @@ -19,7 +19,7 @@ export default function actionsTests({ loadTestFile }: FtrProviderContext) { loadTestFile(require.resolve('./create')); loadTestFile(require.resolve('./delete')); loadTestFile(require.resolve('./execute')); - loadTestFile(require.resolve('./find')); + loadTestFile(require.resolve('./get_all')); loadTestFile(require.resolve('./get')); loadTestFile(require.resolve('./list_action_types')); loadTestFile(require.resolve('./update')); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/update.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/update.ts index a792efede07ee..6cafbeb8c6ea8 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/update.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/update.ts @@ -69,6 +69,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) { expect(response.statusCode).to.eql(200); expect(response.body).to.eql({ id: createdAction.id, + isPreconfigured: false, actionTypeId: 'test.index-record', name: 'My action updated', config: { @@ -307,6 +308,45 @@ export default function updateActionTests({ getService }: FtrProviderContext) { throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`); } }); + + it(`shouldn't update action from preconfigured list`, async () => { + const response = await supertestWithoutAuth + .put(`${getUrlPrefix(space.id)}/api/action/custom-system-abc-connector`) + .auth(user.username, user.password) + .set('kbn-xsrf', 'foo') + .send({ + name: 'My action updated', + config: { + unencrypted: `This value shouldn't get encrypted`, + }, + secrets: { + encrypted: 'This value should be encrypted', + }, + }); + + switch (scenario.id) { + case 'no_kibana_privileges at space1': + case 'space_1_all at space2': + case 'global_read at space1': + expect(response.statusCode).to.eql(404); + expect(response.body).to.eql({ + statusCode: 404, + error: 'Not Found', + message: 'Not Found', + }); + break; + case 'superuser at space1': + case 'space_1_all at space1': + expect(response.body).to.eql({ + statusCode: 400, + error: 'Bad Request', + message: `Preconfigured action custom-system-abc-connector is not allowed to update.`, + }); + break; + default: + throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`); + } + }); }); } }); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/builtin_action_types/es_index.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/builtin_action_types/es_index.ts index 3713e9c24419f..874d42ac04736 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/builtin_action_types/es_index.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/builtin_action_types/es_index.ts @@ -38,6 +38,7 @@ export default function indexTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdAction.id, + isPreconfigured: false, name: 'An index action', actionTypeId: '.index', config: { @@ -55,6 +56,7 @@ export default function indexTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, + isPreconfigured: false, name: 'An index action', actionTypeId: '.index', config: { index: ES_TEST_INDEX_NAME, refresh: false, executionTimeField: null }, @@ -77,6 +79,7 @@ export default function indexTest({ getService }: FtrProviderContext) { expect(createdActionWithIndex).to.eql({ id: createdActionWithIndex.id, + isPreconfigured: false, name: 'An index action with index config', actionTypeId: '.index', config: { @@ -94,6 +97,7 @@ export default function indexTest({ getService }: FtrProviderContext) { expect(fetchedActionWithIndex).to.eql({ id: fetchedActionWithIndex.id, + isPreconfigured: false, name: 'An index action with index config', actionTypeId: '.index', config: { diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/create.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/create.ts index efd707b59cd34..c70c289194abb 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/create.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/create.ts @@ -37,6 +37,7 @@ export default function createActionTests({ getService }: FtrProviderContext) { objectRemover.add(Spaces.space1.id, response.body.id, 'action'); expect(response.body).to.eql({ id: response.body.id, + isPreconfigured: false, name: 'My action', actionTypeId: 'test.index-record', config: { diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/delete.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/delete.ts index 283e51352c272..26a811d2cc512 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/delete.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/delete.ts @@ -76,5 +76,16 @@ export default function deleteActionTests({ getService }: FtrProviderContext) { message: 'Saved object [action/2] not found', }); }); + + it(`shouldn't delete action from preconfigured list`, async () => { + await supertest + .delete(`${getUrlPrefix(Spaces.space1.id)}/api/action/my-slack1`) + .set('kbn-xsrf', 'foo') + .expect(400, { + statusCode: 400, + error: 'Bad Request', + message: `Preconfigured action my-slack1 is not allowed to delete.`, + }); + }); }); } diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/find.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/find.ts deleted file mode 100644 index acbc9edc1f2fb..0000000000000 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/find.ts +++ /dev/null @@ -1,92 +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 { Spaces } from '../../scenarios'; -import { getUrlPrefix, ObjectRemover } from '../../../common/lib'; -import { FtrProviderContext } from '../../../common/ftr_provider_context'; - -// eslint-disable-next-line import/no-default-export -export default function findActionTests({ getService }: FtrProviderContext) { - const supertest = getService('supertest'); - - describe('find', () => { - const objectRemover = new ObjectRemover(supertest); - - afterEach(() => objectRemover.removeAll()); - - it('should handle find action request appropriately', async () => { - const { body: createdAction } = await supertest - .post(`${getUrlPrefix(Spaces.space1.id)}/api/action`) - .set('kbn-xsrf', 'foo') - .send({ - name: 'My action', - actionTypeId: 'test.index-record', - config: { - unencrypted: `This value shouldn't get encrypted`, - }, - secrets: { - encrypted: 'This value should be encrypted', - }, - }) - .expect(200); - objectRemover.add(Spaces.space1.id, createdAction.id, 'action'); - - await supertest - .get( - `${getUrlPrefix( - Spaces.space1.id - )}/api/action/_find?search=test.index-record&search_fields=actionTypeId` - ) - .expect(200, { - page: 1, - perPage: 20, - total: 1, - data: [ - { - id: createdAction.id, - name: 'My action', - actionTypeId: 'test.index-record', - config: { - unencrypted: `This value shouldn't get encrypted`, - }, - referencedByCount: 0, - }, - ], - }); - }); - - it(`shouldn't find action from another space`, async () => { - const { body: createdAction } = await supertest - .post(`${getUrlPrefix(Spaces.space1.id)}/api/action`) - .set('kbn-xsrf', 'foo') - .send({ - name: 'My action', - actionTypeId: 'test.index-record', - config: { - unencrypted: `This value shouldn't get encrypted`, - }, - secrets: { - encrypted: 'This value should be encrypted', - }, - }) - .expect(200); - objectRemover.add(Spaces.space1.id, createdAction.id, 'action'); - - await supertest - .get( - `${getUrlPrefix( - Spaces.other.id - )}/api/action/_find?search=test.index-record&search_fields=actionTypeId` - ) - .expect(200, { - page: 1, - perPage: 20, - total: 0, - data: [], - }); - }); - }); -} diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get.ts index 0f896bfaa0af9..a4a13441fb766 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get.ts @@ -38,6 +38,7 @@ export default function getActionTests({ getService }: FtrProviderContext) { .get(`${getUrlPrefix(Spaces.space1.id)}/api/action/${createdAction.id}`) .expect(200, { id: createdAction.id, + isPreconfigured: false, actionTypeId: 'test.index-record', name: 'My action', config: { @@ -71,5 +72,17 @@ export default function getActionTests({ getService }: FtrProviderContext) { message: `Saved object [action/${createdAction.id}] not found`, }); }); + + it('should handle get action request from preconfigured list', async () => { + await supertest.get(`${getUrlPrefix(Spaces.space1.id)}/api/action/my-slack1`).expect(200, { + id: 'my-slack1', + isPreconfigured: true, + actionTypeId: '.slack', + name: 'Slack#xyz', + config: { + webhookUrl: 'https://hooks.slack.com/services/abcd/efgh/ijklmnopqrstuvwxyz', + }, + }); + }); }); } diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get_all.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get_all.ts new file mode 100644 index 0000000000000..517c64f178af5 --- /dev/null +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get_all.ts @@ -0,0 +1,116 @@ +/* + * 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 { Spaces } from '../../scenarios'; +import { getUrlPrefix, ObjectRemover } from '../../../common/lib'; +import { FtrProviderContext } from '../../../common/ftr_provider_context'; + +// eslint-disable-next-line import/no-default-export +export default function getAllActionTests({ getService }: FtrProviderContext) { + const supertest = getService('supertest'); + + describe('getAll', () => { + const objectRemover = new ObjectRemover(supertest); + + afterEach(() => objectRemover.removeAll()); + + it('should handle get all action request appropriately', async () => { + const { body: createdAction } = await supertest + .post(`${getUrlPrefix(Spaces.space1.id)}/api/action`) + .set('kbn-xsrf', 'foo') + .send({ + name: 'My action', + actionTypeId: 'test.index-record', + config: { + unencrypted: `This value shouldn't get encrypted`, + }, + secrets: { + encrypted: 'This value should be encrypted', + }, + }) + .expect(200); + objectRemover.add(Spaces.space1.id, createdAction.id, 'action'); + + await supertest.get(`${getUrlPrefix(Spaces.space1.id)}/api/action/_getAll`).expect(200, [ + { + id: createdAction.id, + isPreconfigured: false, + name: 'My action', + actionTypeId: 'test.index-record', + config: { + unencrypted: `This value shouldn't get encrypted`, + }, + referencedByCount: 0, + }, + { + id: 'my-slack1', + isPreconfigured: true, + actionTypeId: '.slack', + name: 'Slack#xyz', + config: { + webhookUrl: 'https://hooks.slack.com/services/abcd/efgh/ijklmnopqrstuvwxyz', + }, + referencedByCount: 0, + }, + { + id: 'custom-system-abc-connector', + isPreconfigured: true, + actionTypeId: 'system-abc-action-type', + name: 'SystemABC', + config: { + xyzConfig1: 'value1', + xyzConfig2: 'value2', + listOfThings: ['a', 'b', 'c', 'd'], + }, + referencedByCount: 0, + }, + ]); + }); + + it(`shouldn't get all action from another space`, async () => { + const { body: createdAction } = await supertest + .post(`${getUrlPrefix(Spaces.space1.id)}/api/action`) + .set('kbn-xsrf', 'foo') + .send({ + name: 'My action', + actionTypeId: 'test.index-record', + config: { + unencrypted: `This value shouldn't get encrypted`, + }, + secrets: { + encrypted: 'This value should be encrypted', + }, + }) + .expect(200); + objectRemover.add(Spaces.space1.id, createdAction.id, 'action'); + + await supertest.get(`${getUrlPrefix(Spaces.other.id)}/api/action/_getAll`).expect(200, [ + { + id: 'my-slack1', + isPreconfigured: true, + actionTypeId: '.slack', + name: 'Slack#xyz', + config: { + webhookUrl: 'https://hooks.slack.com/services/abcd/efgh/ijklmnopqrstuvwxyz', + }, + referencedByCount: 0, + }, + { + id: 'custom-system-abc-connector', + isPreconfigured: true, + actionTypeId: 'system-abc-action-type', + name: 'SystemABC', + config: { + xyzConfig1: 'value1', + xyzConfig2: 'value2', + listOfThings: ['a', 'b', 'c', 'd'], + }, + referencedByCount: 0, + }, + ]); + }); + }); +} diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/index.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/index.ts index fb2be8c86f4e8..75544b7fd4169 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/index.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/index.ts @@ -11,7 +11,7 @@ export default function actionsTests({ loadTestFile }: FtrProviderContext) { describe('Actions', () => { loadTestFile(require.resolve('./create')); loadTestFile(require.resolve('./delete')); - loadTestFile(require.resolve('./find')); + loadTestFile(require.resolve('./get_all')); loadTestFile(require.resolve('./get')); loadTestFile(require.resolve('./list_action_types')); loadTestFile(require.resolve('./update')); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/type_not_enabled.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/type_not_enabled.ts index 18a0ecc23c1e1..2593f342a8a86 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/type_not_enabled.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/type_not_enabled.ts @@ -63,6 +63,7 @@ export default function typeNotEnabledTests({ getService }: FtrProviderContext) actionTypeId: 'test.not-enabled', config: {}, id: 'uuid-actionId', + isPreconfigured: false, name: 'an action created before test.not-enabled was disabled', }); }); @@ -89,6 +90,7 @@ export default function typeNotEnabledTests({ getService }: FtrProviderContext) actionTypeId: 'test.not-enabled', config: {}, id: 'uuid-actionId', + isPreconfigured: false, name: 'an action created before test.not-enabled was disabled', }); }); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/update.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/update.ts index fb0c5e13c0720..05d26aaaed2ec 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/update.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/update.ts @@ -48,6 +48,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) { }) .expect(200, { id: createdAction.id, + isPreconfigured: false, actionTypeId: 'test.index-record', name: 'My action updated', config: { @@ -99,5 +100,25 @@ export default function updateActionTests({ getService }: FtrProviderContext) { message: `Saved object [action/${createdAction.id}] not found`, }); }); + + it(`shouldn't update action from preconfigured list`, async () => { + await supertest + .put(`${getUrlPrefix(Spaces.space1.id)}/api/action/custom-system-abc-connector`) + .set('kbn-xsrf', 'foo') + .send({ + name: 'My action updated', + config: { + unencrypted: `This value shouldn't get encrypted`, + }, + secrets: { + encrypted: 'This value should be encrypted', + }, + }) + .expect(400, { + statusCode: 400, + error: 'Bad Request', + message: `Preconfigured action custom-system-abc-connector is not allowed to update.`, + }); + }); }); } From 9d89a4fb4900a372c2445f0359374da8d9030515 Mon Sep 17 00:00:00 2001 From: Larry Gregory Date: Wed, 8 Apr 2020 13:03:15 -0400 Subject: [PATCH 17/40] Support multiple reserved feature privileges (#61980) * support multiple reserved feature privileges * update reserved privilege ids * additional testing * Add ml_user and ml_admin reserved privileges * prrevent reserved privilege ids from sttarting with 'reserved_' * address pr feedback: dedicated reserved privilege type * re-enable ML test suites Co-authored-by: Elastic Machine --- x-pack/plugins/features/common/feature.ts | 3 +- .../common/reserved_kibana_privilege.ts | 12 + .../features/server/feature_registry.test.ts | 254 +++++++++++++----- .../features/server/feature_registry.ts | 4 +- .../plugins/features/server/feature_schema.ts | 16 +- x-pack/plugins/ml/server/plugin.ts | 35 ++- x-pack/plugins/monitoring/server/plugin.ts | 23 +- .../security/server/authorization/index.ts | 5 +- .../privileges/privileges.test.ts | 51 ++-- .../authorization/privileges/privileges.ts | 10 +- .../validate_feature_privileges.test.ts | 17 +- .../validate_reserved_privileges.test.ts | 181 +++++++++++++ .../validate_reserved_privileges.ts | 20 ++ x-pack/test/api_integration/apis/ml/index.ts | 5 +- .../apis/security/privileges.ts | 2 +- .../apis/security/privileges_basic.ts | 2 +- .../functional/apps/machine_learning/index.ts | 5 +- 17 files changed, 512 insertions(+), 133 deletions(-) create mode 100644 x-pack/plugins/features/common/reserved_kibana_privilege.ts create mode 100644 x-pack/plugins/security/server/authorization/validate_reserved_privileges.test.ts create mode 100644 x-pack/plugins/security/server/authorization/validate_reserved_privileges.ts diff --git a/x-pack/plugins/features/common/feature.ts b/x-pack/plugins/features/common/feature.ts index 82fcc33f5c8ce..ef32a8a80a0bd 100644 --- a/x-pack/plugins/features/common/feature.ts +++ b/x-pack/plugins/features/common/feature.ts @@ -7,6 +7,7 @@ import { RecursiveReadonly } from '@kbn/utility-types'; import { FeatureKibanaPrivileges } from './feature_kibana_privileges'; import { SubFeatureConfig, SubFeature } from './sub_feature'; +import { ReservedKibanaPrivilege } from './reserved_kibana_privilege'; /** * Interface for registering a feature. @@ -122,8 +123,8 @@ export interface FeatureConfig { * @private */ reserved?: { - privilege: FeatureKibanaPrivileges; description: string; + privileges: ReservedKibanaPrivilege[]; }; } diff --git a/x-pack/plugins/features/common/reserved_kibana_privilege.ts b/x-pack/plugins/features/common/reserved_kibana_privilege.ts new file mode 100644 index 0000000000000..0186011382e84 --- /dev/null +++ b/x-pack/plugins/features/common/reserved_kibana_privilege.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { FeatureKibanaPrivileges } from '.'; + +export interface ReservedKibanaPrivilege { + id: string; + privilege: FeatureKibanaPrivileges; +} diff --git a/x-pack/plugins/features/server/feature_registry.test.ts b/x-pack/plugins/features/server/feature_registry.test.ts index 5b4f7728c9f31..2039f8f6acda2 100644 --- a/x-pack/plugins/features/server/feature_registry.test.ts +++ b/x-pack/plugins/features/server/feature_registry.test.ts @@ -110,19 +110,24 @@ describe('FeatureRegistry', () => { ], privilegesTooltip: 'some fancy tooltip', reserved: { - privilege: { - catalogue: ['foo'], - management: { - foo: ['bar'], - }, - app: ['app1'], - savedObject: { - all: ['space', 'etc', 'telemetry'], - read: ['canvas', 'config', 'url'], + privileges: [ + { + id: 'reserved', + privilege: { + catalogue: ['foo'], + management: { + foo: ['bar'], + }, + app: ['app1'], + savedObject: { + all: ['space', 'etc', 'telemetry'], + read: ['canvas', 'config', 'url'], + }, + api: ['someApiEndpointTag', 'anotherEndpointTag'], + ui: ['allowsFoo', 'showBar', 'showBaz'], + }, }, - api: ['someApiEndpointTag', 'anotherEndpointTag'], - ui: ['allowsFoo', 'showBar', 'showBaz'], - }, + ], description: 'some completely adequate description', }, }; @@ -264,13 +269,18 @@ describe('FeatureRegistry', () => { privileges: null, reserved: { description: 'foo', - privilege: { - ui: [], - savedObject: { - all: [], - read: [], + privileges: [ + { + id: 'reserved', + privilege: { + ui: [], + savedObject: { + all: [], + read: [], + }, + }, }, - }, + ], }, }; @@ -278,7 +288,7 @@ describe('FeatureRegistry', () => { featureRegistry.register(feature); const result = featureRegistry.getAll(); - const reservedPrivilege = result[0]!.reserved!.privilege; + const reservedPrivilege = result[0]!.reserved!.privileges[0].privilege; expect(reservedPrivilege.savedObject.all).toEqual(['telemetry']); expect(reservedPrivilege.savedObject.read).toEqual(['config', 'url']); }); @@ -520,14 +530,19 @@ describe('FeatureRegistry', () => { privileges: null, reserved: { description: 'something', - privilege: { - savedObject: { - all: [], - read: [], + privileges: [ + { + id: 'reserved', + privilege: { + savedObject: { + all: [], + read: [], + }, + ui: [], + app: ['foo', 'bar', 'baz'], + }, }, - ui: [], - app: ['foo', 'bar', 'baz'], - }, + ], }, }; @@ -546,14 +561,19 @@ describe('FeatureRegistry', () => { privileges: null, reserved: { description: 'something', - privilege: { - savedObject: { - all: [], - read: [], + privileges: [ + { + id: 'reserved', + privilege: { + savedObject: { + all: [], + read: [], + }, + ui: [], + app: ['foo', 'bar'], + }, }, - ui: [], - app: ['foo', 'bar'], - }, + ], }, }; @@ -666,15 +686,20 @@ describe('FeatureRegistry', () => { privileges: null, reserved: { description: 'something', - privilege: { - catalogue: ['foo', 'bar', 'baz'], - savedObject: { - all: [], - read: [], + privileges: [ + { + id: 'reserved', + privilege: { + catalogue: ['foo', 'bar', 'baz'], + savedObject: { + all: [], + read: [], + }, + ui: [], + app: [], + }, }, - ui: [], - app: [], - }, + ], }, }; @@ -694,15 +719,20 @@ describe('FeatureRegistry', () => { privileges: null, reserved: { description: 'something', - privilege: { - catalogue: ['foo', 'bar'], - savedObject: { - all: [], - read: [], + privileges: [ + { + id: 'reserved', + privilege: { + catalogue: ['foo', 'bar'], + savedObject: { + all: [], + read: [], + }, + ui: [], + app: [], + }, }, - ui: [], - app: [], - }, + ], }, }; @@ -840,18 +870,23 @@ describe('FeatureRegistry', () => { privileges: null, reserved: { description: 'something', - privilege: { - catalogue: ['bar'], - management: { - kibana: ['hey-there'], - }, - savedObject: { - all: [], - read: [], + privileges: [ + { + id: 'reserved', + privilege: { + catalogue: ['bar'], + management: { + kibana: ['hey-there'], + }, + savedObject: { + all: [], + read: [], + }, + ui: [], + app: [], + }, }, - ui: [], - app: [], - }, + ], }, }; @@ -874,18 +909,23 @@ describe('FeatureRegistry', () => { privileges: null, reserved: { description: 'something', - privilege: { - catalogue: ['bar'], - management: { - kibana: ['hey-there'], - }, - savedObject: { - all: [], - read: [], + privileges: [ + { + id: 'reserved', + privilege: { + catalogue: ['bar'], + management: { + kibana: ['hey-there'], + }, + savedObject: { + all: [], + read: [], + }, + ui: [], + app: [], + }, }, - ui: [], - app: [], - }, + ], }, }; @@ -896,6 +936,78 @@ describe('FeatureRegistry', () => { ); }); + it('allows multiple reserved feature privileges to be registered', () => { + const feature: FeatureConfig = { + id: 'test-feature', + name: 'Test Feature', + app: [], + privileges: null, + reserved: { + description: 'my reserved privileges', + privileges: [ + { + id: 'a_reserved_1', + privilege: { + savedObject: { + all: [], + read: [], + }, + ui: [], + app: [], + }, + }, + { + id: 'a_reserved_2', + privilege: { + savedObject: { + all: [], + read: [], + }, + ui: [], + app: [], + }, + }, + ], + }, + }; + + const featureRegistry = new FeatureRegistry(); + featureRegistry.register(feature); + const result = featureRegistry.getAll(); + expect(result).toHaveLength(1); + expect(result[0].reserved?.privileges).toHaveLength(2); + }); + + it('does not allow reserved privilege ids to start with "reserved_"', () => { + const feature: FeatureConfig = { + id: 'test-feature', + name: 'Test Feature', + app: [], + privileges: null, + reserved: { + description: 'my reserved privileges', + privileges: [ + { + id: 'reserved_1', + privilege: { + savedObject: { + all: [], + read: [], + }, + ui: [], + app: [], + }, + }, + ], + }, + }; + + const featureRegistry = new FeatureRegistry(); + expect(() => featureRegistry.register(feature)).toThrowErrorMatchingInlineSnapshot( + `"child \\"reserved\\" fails because [child \\"privileges\\" fails because [\\"privileges\\" at position 0 fails because [child \\"id\\" fails because [\\"id\\" with value \\"reserved_1\\" fails to match the required pattern: /^(?!reserved_)[a-zA-Z0-9_-]+$/]]]]"` + ); + }); + it('cannot register feature after getAll has been called', () => { const feature1: FeatureConfig = { id: 'test-feature', diff --git a/x-pack/plugins/features/server/feature_registry.ts b/x-pack/plugins/features/server/feature_registry.ts index 73a353cd27471..6140b7ac87ce0 100644 --- a/x-pack/plugins/features/server/feature_registry.ts +++ b/x-pack/plugins/features/server/feature_registry.ts @@ -39,9 +39,9 @@ export class FeatureRegistry { function applyAutomaticPrivilegeGrants(feature: FeatureConfig): FeatureConfig { const allPrivilege = feature.privileges?.all; const readPrivilege = feature.privileges?.read; - const reservedPrivilege = feature.reserved?.privilege; + const reservedPrivileges = (feature.reserved?.privileges ?? []).map(rp => rp.privilege); - applyAutomaticAllPrivilegeGrants(allPrivilege, reservedPrivilege); + applyAutomaticAllPrivilegeGrants(allPrivilege, ...reservedPrivileges); applyAutomaticReadPrivilegeGrants(readPrivilege); return feature; diff --git a/x-pack/plugins/features/server/feature_schema.ts b/x-pack/plugins/features/server/feature_schema.ts index fdeceb30b4e3d..403d9586bf160 100644 --- a/x-pack/plugins/features/server/feature_schema.ts +++ b/x-pack/plugins/features/server/feature_schema.ts @@ -18,6 +18,7 @@ const prohibitedFeatureIds: Array = ['catalogue', 'managem const featurePrivilegePartRegex = /^[a-zA-Z0-9_-]+$/; const subFeaturePrivilegePartRegex = /^[a-zA-Z0-9_-]+$/; const managementSectionIdRegex = /^[a-zA-Z0-9_-]+$/; +const reservedFeaturePrrivilegePartRegex = /^(?!reserved_)[a-zA-Z0-9_-]+$/; export const uiCapabilitiesRegex = /^[a-zA-Z0-9:_-]+$/; const managementSchema = Joi.object().pattern( @@ -118,8 +119,17 @@ const schema = Joi.object({ }), privilegesTooltip: Joi.string(), reserved: Joi.object({ - privilege: privilegeSchema.required(), description: Joi.string().required(), + privileges: Joi.array() + .items( + Joi.object({ + id: Joi.string() + .regex(reservedFeaturePrrivilegePartRegex) + .required(), + privilege: privilegeSchema.required(), + }) + ) + .required(), }), }); @@ -209,7 +219,9 @@ export function validateFeature(feature: FeatureConfig) { privilegeEntries.push(...Object.entries(feature.privileges)); } if (feature.reserved) { - privilegeEntries.push(['reserved', feature.reserved.privilege]); + feature.reserved.privileges.forEach(reservedPrivilege => { + privilegeEntries.push([reservedPrivilege.id, reservedPrivilege.privilege]); + }); } if (privilegeEntries.length === 0) { diff --git a/x-pack/plugins/ml/server/plugin.ts b/x-pack/plugins/ml/server/plugin.ts index 7d3ef116e67ab..c7add12be142c 100644 --- a/x-pack/plugins/ml/server/plugin.ts +++ b/x-pack/plugins/ml/server/plugin.ts @@ -79,19 +79,36 @@ export class MlServerPlugin implements Plugin { - validateFeaturePrivileges(featuresService.getFeatures()); + const features = featuresService.getFeatures(); + validateFeaturePrivileges(features); + validateReservedPrivileges(features); await registerPrivilegesWithCluster(logger, privileges, applicationName, clusterClient); }, diff --git a/x-pack/plugins/security/server/authorization/privileges/privileges.test.ts b/x-pack/plugins/security/server/authorization/privileges/privileges.test.ts index 3d25fc03f568b..b023c12d35b79 100644 --- a/x-pack/plugins/security/server/authorization/privileges/privileges.test.ts +++ b/x-pack/plugins/security/server/authorization/privileges/privileges.test.ts @@ -409,13 +409,18 @@ describe('features', () => { }, privileges: null, reserved: { - privilege: { - savedObject: { - all: ['ignore-me-1', 'ignore-me-2'], - read: ['ignore-me-1', 'ignore-me-2'], + privileges: [ + { + id: 'reserved', + privilege: { + savedObject: { + all: ['ignore-me-1', 'ignore-me-2'], + read: ['ignore-me-1', 'ignore-me-2'], + }, + ui: ['ignore-me-1'], + }, }, - ui: ['ignore-me-1'], - }, + ], description: '', }, }), @@ -591,13 +596,18 @@ describe('reserved', () => { }, privileges: null, reserved: { - privilege: { - savedObject: { - all: [], - read: [], + privileges: [ + { + id: 'foo', + privilege: { + savedObject: { + all: [], + read: [], + }, + ui: [], + }, }, - ui: [], - }, + ], description: '', }, }), @@ -627,13 +637,18 @@ describe('reserved', () => { app: [], privileges: null, reserved: { - privilege: { - savedObject: { - all: ['savedObject-all-1', 'savedObject-all-2'], - read: ['savedObject-read-1', 'savedObject-read-2'], + privileges: [ + { + id: 'foo', + privilege: { + savedObject: { + all: ['savedObject-all-1', 'savedObject-all-2'], + read: ['savedObject-read-1', 'savedObject-read-2'], + }, + ui: ['ui-1', 'ui-2'], + }, }, - ui: ['ui-1', 'ui-2'], - }, + ], description: '', }, }), diff --git a/x-pack/plugins/security/server/authorization/privileges/privileges.ts b/x-pack/plugins/security/server/authorization/privileges/privileges.ts index b25aad30a3423..9a8935f80a174 100644 --- a/x-pack/plugins/security/server/authorization/privileges/privileges.ts +++ b/x-pack/plugins/security/server/authorization/privileges/privileges.ts @@ -110,10 +110,12 @@ export function privilegesFactory( }, reserved: features.reduce((acc: Record, feature: Feature) => { if (feature.reserved) { - acc[feature.id] = [ - actions.version, - ...featurePrivilegeBuilder.getActions(feature.reserved!.privilege, feature), - ]; + feature.reserved.privileges.forEach(reservedPrivilege => { + acc[reservedPrivilege.id] = [ + actions.version, + ...uniq(featurePrivilegeBuilder.getActions(reservedPrivilege.privilege, feature)), + ]; + }); } return acc; }, {}), diff --git a/x-pack/plugins/security/server/authorization/validate_feature_privileges.test.ts b/x-pack/plugins/security/server/authorization/validate_feature_privileges.test.ts index ac386d287cff1..cd2c7faa263c9 100644 --- a/x-pack/plugins/security/server/authorization/validate_feature_privileges.test.ts +++ b/x-pack/plugins/security/server/authorization/validate_feature_privileges.test.ts @@ -26,13 +26,18 @@ it('allows features with reserved privileges to be defined', () => { privileges: null, reserved: { description: 'foo', - privilege: { - savedObject: { - all: ['foo'], - read: ['bar'], + privileges: [ + { + id: 'reserved', + privilege: { + savedObject: { + all: ['foo'], + read: ['bar'], + }, + ui: [], + }, }, - ui: [], - }, + ], }, }); diff --git a/x-pack/plugins/security/server/authorization/validate_reserved_privileges.test.ts b/x-pack/plugins/security/server/authorization/validate_reserved_privileges.test.ts new file mode 100644 index 0000000000000..26af0dadfb288 --- /dev/null +++ b/x-pack/plugins/security/server/authorization/validate_reserved_privileges.test.ts @@ -0,0 +1,181 @@ +/* + * 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 { Feature } from '../../../features/server'; +import { validateReservedPrivileges } from './validate_reserved_privileges'; + +it('allows features to be defined without privileges', () => { + const feature: Feature = new Feature({ + id: 'foo', + name: 'foo', + app: [], + privileges: null, + }); + + validateReservedPrivileges([feature]); +}); + +it('allows features with a single reserved privilege to be defined', () => { + const feature: Feature = new Feature({ + id: 'foo', + name: 'foo', + app: [], + privileges: null, + reserved: { + description: 'foo', + privileges: [ + { + id: 'reserved', + privilege: { + savedObject: { + all: ['foo'], + read: ['bar'], + }, + ui: [], + }, + }, + ], + }, + }); + + validateReservedPrivileges([feature]); +}); + +it('allows multiple features with reserved privileges to be defined', () => { + const feature1: Feature = new Feature({ + id: 'foo', + name: 'foo', + app: [], + privileges: null, + reserved: { + description: 'foo', + privileges: [ + { + id: 'reserved-1', + privilege: { + savedObject: { + all: ['foo'], + read: ['bar'], + }, + ui: [], + }, + }, + ], + }, + }); + + const feature2: Feature = new Feature({ + id: 'foo2', + name: 'foo', + app: [], + privileges: null, + reserved: { + description: 'foo', + privileges: [ + { + id: 'reserved-2', + privilege: { + savedObject: { + all: ['foo'], + read: ['bar'], + }, + ui: [], + }, + }, + ], + }, + }); + + validateReservedPrivileges([feature1, feature2]); +}); + +it('prevents a feature from specifying the same reserved privilege id', () => { + const feature1: Feature = new Feature({ + id: 'foo', + name: 'foo', + app: [], + privileges: null, + reserved: { + description: 'foo', + privileges: [ + { + id: 'reserved', + privilege: { + savedObject: { + all: ['foo'], + read: ['bar'], + }, + ui: [], + }, + }, + { + id: 'reserved', + privilege: { + savedObject: { + all: ['foo'], + read: ['bar'], + }, + ui: [], + }, + }, + ], + }, + }); + + expect(() => validateReservedPrivileges([feature1])).toThrowErrorMatchingInlineSnapshot( + `"Duplicate reserved privilege id detected: reserved. This is not allowed."` + ); +}); + +it('prevents features from sharing a reserved privilege id', () => { + const feature1: Feature = new Feature({ + id: 'foo', + name: 'foo', + app: [], + privileges: null, + reserved: { + description: 'foo', + privileges: [ + { + id: 'reserved', + privilege: { + savedObject: { + all: ['foo'], + read: ['bar'], + }, + ui: [], + }, + }, + ], + }, + }); + + const feature2: Feature = new Feature({ + id: 'foo2', + name: 'foo', + app: [], + privileges: null, + reserved: { + description: 'foo', + privileges: [ + { + id: 'reserved', + privilege: { + savedObject: { + all: ['foo'], + read: ['bar'], + }, + ui: [], + }, + }, + ], + }, + }); + + expect(() => validateReservedPrivileges([feature1, feature2])).toThrowErrorMatchingInlineSnapshot( + `"Duplicate reserved privilege id detected: reserved. This is not allowed."` + ); +}); diff --git a/x-pack/plugins/security/server/authorization/validate_reserved_privileges.ts b/x-pack/plugins/security/server/authorization/validate_reserved_privileges.ts new file mode 100644 index 0000000000000..0915308fc0f89 --- /dev/null +++ b/x-pack/plugins/security/server/authorization/validate_reserved_privileges.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 { Feature } from '../../../features/server'; + +export function validateReservedPrivileges(features: Feature[]) { + const seenPrivilegeIds = new Set(); + + for (const feature of features) { + (feature?.reserved?.privileges ?? []).forEach(({ id }) => { + if (seenPrivilegeIds.has(id)) { + throw new Error(`Duplicate reserved privilege id detected: ${id}. This is not allowed.`); + } + seenPrivilegeIds.add(id); + }); + } +} diff --git a/x-pack/test/api_integration/apis/ml/index.ts b/x-pack/test/api_integration/apis/ml/index.ts index bcba156a64f0e..4e21faa610bfe 100644 --- a/x-pack/test/api_integration/apis/ml/index.ts +++ b/x-pack/test/api_integration/apis/ml/index.ts @@ -9,10 +9,7 @@ import { FtrProviderContext } from '../../ftr_provider_context'; export default function({ getService, loadTestFile }: FtrProviderContext) { const ml = getService('ml'); - // ML tests need to be disabled in orde to get the ES snapshot with - // https://github.com/elastic/elasticsearch/pull/54713 promoted - // and should be re-enabled as part of https://github.com/elastic/kibana/pull/61980 - describe.skip('Machine Learning', function() { + describe('Machine Learning', function() { this.tags(['mlqa']); before(async () => { diff --git a/x-pack/test/api_integration/apis/security/privileges.ts b/x-pack/test/api_integration/apis/security/privileges.ts index 77293ddff3f9f..9bec3fd076e86 100644 --- a/x-pack/test/api_integration/apis/security/privileges.ts +++ b/x-pack/test/api_integration/apis/security/privileges.ts @@ -41,7 +41,7 @@ export default function({ getService }: FtrProviderContext) { }, global: ['all', 'read'], space: ['all', 'read'], - reserved: ['ml', 'monitoring'], + reserved: ['ml_user', 'ml_admin', 'monitoring'], }; await supertest diff --git a/x-pack/test/api_integration/apis/security/privileges_basic.ts b/x-pack/test/api_integration/apis/security/privileges_basic.ts index 0b29fc1cac7de..1f9eac148b302 100644 --- a/x-pack/test/api_integration/apis/security/privileges_basic.ts +++ b/x-pack/test/api_integration/apis/security/privileges_basic.ts @@ -39,7 +39,7 @@ export default function({ getService }: FtrProviderContext) { }, global: ['all', 'read'], space: ['all', 'read'], - reserved: ['ml', 'monitoring'], + reserved: ['ml_user', 'ml_admin', 'monitoring'], }; await supertest diff --git a/x-pack/test/functional/apps/machine_learning/index.ts b/x-pack/test/functional/apps/machine_learning/index.ts index 143899a61ffb9..47c699e309491 100644 --- a/x-pack/test/functional/apps/machine_learning/index.ts +++ b/x-pack/test/functional/apps/machine_learning/index.ts @@ -8,10 +8,7 @@ import { FtrProviderContext } from '../../ftr_provider_context'; export default function({ getService, loadTestFile }: FtrProviderContext) { const ml = getService('ml'); - // ML tests need to be disabled in orde to get the ES snapshot with - // https://github.com/elastic/elasticsearch/pull/54713 promoted - // and should be re-enabled as part of https://github.com/elastic/kibana/pull/61980 - describe.skip('machine learning', function() { + describe('machine learning', function() { this.tags('ciGroup3'); before(async () => { From 3e4469c99c28f8bb1b517bf2ed41539af73f4ffa Mon Sep 17 00:00:00 2001 From: Melissa Alvarez Date: Wed, 8 Apr 2020 13:13:40 -0400 Subject: [PATCH 18/40] [ML] Analytics: ensure both keyword/text types are excluded for selected excluded field (#62712) * exclude keyword and text types of field selected for exclusion * only show keyword type fields of accepted fields for depVar * make excludes field logic generic * fix regex to ensure escaped dot. reset regex and mainfield * ensure cloned jobs get correct excluded fields * add clarifying comments --- .../create_analytics_form.tsx | 2 +- .../form_options_validation.ts | 2 +- .../hooks/use_create_analytics_form/state.ts | 52 ++++++++++++++++++- 3 files changed, 53 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/create_analytics_form/create_analytics_form.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/create_analytics_form/create_analytics_form.tsx index e5f30a50ed8f0..0c83dfb6a2346 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/create_analytics_form/create_analytics_form.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/create_analytics_form/create_analytics_form.tsx @@ -250,7 +250,7 @@ export const CreateAnalyticsForm: FC = ({ actions, sta dependentVariableOptions: [] as State['form']['dependentVariableOptions'], }; - await newJobCapsService.initializeFromIndexPattern(indexPattern); + await newJobCapsService.initializeFromIndexPattern(indexPattern, false, false); // Get fields and filter for supported types for job type const { fields } = newJobCapsService; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/create_analytics_form/form_options_validation.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/create_analytics_form/form_options_validation.ts index 9c0bc69f4b41f..4bd03fec7cc72 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/create_analytics_form/form_options_validation.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/create_analytics_form/form_options_validation.ts @@ -10,7 +10,7 @@ import { ANALYSIS_CONFIG_TYPE } from '../../../../common/analytics'; import { AnalyticsJobType } from '../../hooks/use_create_analytics_form/state'; import { BASIC_NUMERICAL_TYPES, EXTENDED_NUMERICAL_TYPES } from '../../../../common/fields'; -const CATEGORICAL_TYPES = new Set(['ip', 'keyword', 'text']); +const CATEGORICAL_TYPES = new Set(['ip', 'keyword']); // List of system fields we want to ignore for the numeric field check. export const OMIT_FIELDS: string[] = ['_source', '_type', '_index', '_id', '_version', '_score']; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/state.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/state.ts index 01a39d2ef9f3b..e121268e65e86 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/state.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/state.ts @@ -8,6 +8,7 @@ import { EuiComboBoxOptionOption } from '@elastic/eui'; import { DeepPartial, DeepReadonly } from '../../../../../../../common/types/common'; import { checkPermission } from '../../../../../privilege/check_privilege'; import { mlNodesAvailable } from '../../../../../ml_nodes_check'; +import { newJobCapsService } from '../../../../../services/new_job_capabilities_service'; import { isClassificationAnalysis, @@ -158,6 +159,55 @@ export const getInitialState = (): State => ({ estimatedModelMemoryLimit: '', }); +const getExcludesFields = (excluded: string[]) => { + const { fields } = newJobCapsService; + const updatedExcluded: string[] = []; + // Loop through excluded fields to check for multiple types of same field + for (let i = 0; i < excluded.length; i++) { + const fieldName = excluded[i]; + let mainField; + + // No dot in fieldName - it is the main field + if (fieldName.includes('.') === false) { + mainField = fieldName; + } else { + // Dot in fieldName - check if there's a field whose name equals the fieldName with the last dot suffix removed + const regex = /\.[^.]*$/; + const suffixRemovedField = fieldName.replace(regex, ''); + const fieldMatch = newJobCapsService.getFieldById(suffixRemovedField); + + // There's a match - set as the main field + if (fieldMatch !== null) { + mainField = suffixRemovedField; + } else { + // No main field to be found - add the fieldName to updatedExcluded array if it's not already there + if (updatedExcluded.includes(fieldName) === false) { + updatedExcluded.push(fieldName); + } + } + } + + if (mainField !== undefined) { + // Add the main field to the updatedExcluded array if it's not already there + if (updatedExcluded.includes(mainField) === false) { + updatedExcluded.push(mainField); + } + // Create regex to find all other fields whose names begin with main field followed by a dot + const regex = new RegExp(`${mainField}\\..+`); + + // Loop through fields and add fields matching the pattern to updatedExcluded array + for (let j = 0; j < fields.length; j++) { + const field = fields[j].name; + if (updatedExcluded.includes(field) === false && field.match(regex) !== null) { + updatedExcluded.push(field); + } + } + } + } + + return updatedExcluded; +}; + export const getJobConfigFromFormState = ( formState: State['form'] ): DeepPartial => { @@ -175,7 +225,7 @@ export const getJobConfigFromFormState = ( index: formState.destinationIndex, }, analyzed_fields: { - excludes: formState.excludes, + excludes: getExcludesFields(formState.excludes), }, analysis: { outlier_detection: {}, From 56fa9a5776631ad1699393ae323f9e0ebabb117f Mon Sep 17 00:00:00 2001 From: spalger Date: Wed, 8 Apr 2020 10:17:05 -0700 Subject: [PATCH 19/40] skip flaky suite (#59030) --- .../components/load_mappings/load_mappings_provider.test.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/load_mappings/load_mappings_provider.test.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/load_mappings/load_mappings_provider.test.tsx index da4b8e6f6eef2..95630a6981843 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/load_mappings/load_mappings_provider.test.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/load_mappings/load_mappings_provider.test.tsx @@ -51,7 +51,8 @@ const openModalWithJsonContent = ({ find, waitFor }: TestBed) => async (json: an }); }; -describe('', () => { +// FLAKY: https://github.com/elastic/kibana/issues/59030 +describe.skip('', () => { test('it should forward valid mapping definition', async () => { const mappingsToLoad = { properties: { From bfdccfdbc54f98e0c41cfc22665c5e424ec462a0 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Wed, 8 Apr 2020 11:22:52 -0600 Subject: [PATCH 20/40] [Maps] Show create filter button for top-term tooltip property (#62461) * [Maps] Show create filter button top-term tooltip property * add missing imports * update import for NP migration Co-authored-by: Elastic Machine --- .../maps/public/layers/fields/es_agg_field.ts | 2 +- .../layers/tooltips/es_agg_tooltip_property.ts | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/maps/public/layers/fields/es_agg_field.ts b/x-pack/plugins/maps/public/layers/fields/es_agg_field.ts index 65f952ca01038..34f7dd4b9578f 100644 --- a/x-pack/plugins/maps/public/layers/fields/es_agg_field.ts +++ b/x-pack/plugins/maps/public/layers/fields/es_agg_field.ts @@ -90,7 +90,7 @@ export class ESAggField implements IESAggField { async createTooltipProperty(value: string | undefined): Promise { const indexPattern = await this._source.getIndexPattern(); const tooltipProperty = new TooltipProperty(this.getName(), await this.getLabel(), value); - return new ESAggTooltipProperty(tooltipProperty, indexPattern, this); + return new ESAggTooltipProperty(tooltipProperty, indexPattern, this, this.getAggType()); } getValueAggDsl(indexPattern: IndexPattern): unknown | null { diff --git a/x-pack/plugins/maps/public/layers/tooltips/es_agg_tooltip_property.ts b/x-pack/plugins/maps/public/layers/tooltips/es_agg_tooltip_property.ts index 24011c51ddbaa..acd05475f9762 100644 --- a/x-pack/plugins/maps/public/layers/tooltips/es_agg_tooltip_property.ts +++ b/x-pack/plugins/maps/public/layers/tooltips/es_agg_tooltip_property.ts @@ -4,9 +4,25 @@ * you may not use this file except in compliance with the Elastic License. */ import { ESTooltipProperty } from './es_tooltip_property'; +import { AGG_TYPE } from '../../../common/constants'; +import { ITooltipProperty } from './tooltip_property'; +import { IField } from '../fields/field'; +import { IndexPattern } from '../../../../../../src/plugins/data/public'; export class ESAggTooltipProperty extends ESTooltipProperty { + private readonly _aggType: AGG_TYPE; + + constructor( + tooltipProperty: ITooltipProperty, + indexPattern: IndexPattern, + field: IField, + aggType: AGG_TYPE + ) { + super(tooltipProperty, indexPattern, field); + this._aggType = aggType; + } + isFilterable(): boolean { - return false; + return this._aggType === AGG_TYPE.TERMS; } } From 8cacbdfaa5242c3b251ac334c1a31a98da6933a2 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Wed, 8 Apr 2020 19:23:16 +0200 Subject: [PATCH 21/40] [Uptime]Alerting UI text in case filter is selected (#62570) Co-authored-by: Elastic Machine --- .../alerts/uptime_alerts_flyout_wrapper.tsx | 4 ++-- .../functional/alerts/alert_monitor_status.tsx | 16 +++++++++++++++- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/x-pack/legacy/plugins/uptime/public/components/connected/alerts/uptime_alerts_flyout_wrapper.tsx b/x-pack/legacy/plugins/uptime/public/components/connected/alerts/uptime_alerts_flyout_wrapper.tsx index b547f8b076f93..a49468ad3dd06 100644 --- a/x-pack/legacy/plugins/uptime/public/components/connected/alerts/uptime_alerts_flyout_wrapper.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/connected/alerts/uptime_alerts_flyout_wrapper.tsx @@ -17,7 +17,7 @@ interface Props { export const UptimeAlertsFlyoutWrapper = ({ alertTypeId, canChangeTrigger }: Props) => { const dispatch = useDispatch(); - const setAddFlyoutVisiblity = (value: React.SetStateAction) => + const setAddFlyoutVisibility = (value: React.SetStateAction) => // @ts-ignore the value here is a boolean, and it works with the action creator function dispatch(setAlertFlyoutVisible(value)); @@ -28,7 +28,7 @@ export const UptimeAlertsFlyoutWrapper = ({ alertTypeId, canChangeTrigger }: Pro alertFlyoutVisible={alertFlyoutVisible} alertTypeId={alertTypeId} canChangeTrigger={canChangeTrigger} - setAlertFlyoutVisibility={setAddFlyoutVisiblity} + setAlertFlyoutVisibility={setAddFlyoutVisibility} /> ); }; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/alerts/alert_monitor_status.tsx b/x-pack/legacy/plugins/uptime/public/components/functional/alerts/alert_monitor_status.tsx index 5143e1c963904..b86e85f35b17d 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/alerts/alert_monitor_status.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/functional/alerts/alert_monitor_status.tsx @@ -268,7 +268,21 @@ export const AlertMonitorStatusComponent: React.FC = pr /> } data-test-subj="xpack.uptime.alerts.monitorStatus.numTimesExpression" - description="any monitor is down >" + description={ + filters + ? i18n.translate( + 'xpack.uptime.alerts.monitorStatus.numTimesExpression.matchingMonitors.description', + { + defaultMessage: 'matching monitors are down >', + } + ) + : i18n.translate( + 'xpack.uptime.alerts.monitorStatus.numTimesExpression.anyMonitors.description', + { + defaultMessage: 'any monitor is down >', + } + ) + } id="ping-count" value={`${numTimes} times`} /> From 3598b8c44c84165e282aeff234f51417c3c54f96 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Wed, 8 Apr 2020 11:24:04 -0600 Subject: [PATCH 22/40] [Maps] fix attribution overflow with exit full screen button (#62699) * [Maps] fix attribution overflow with exit full screen button * use margin-left instead of padding-left Co-authored-by: Elastic Machine --- .../attribution_control/_attribution_control.scss | 4 ++++ .../widget_overlay/attribution_control/index.js | 2 ++ .../widget_overlay/attribution_control/view.js | 7 ++++++- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/attribution_control/_attribution_control.scss b/x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/attribution_control/_attribution_control.scss index 9ebaee57fba4d..e319535b4a45c 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/attribution_control/_attribution_control.scss +++ b/x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/attribution_control/_attribution_control.scss @@ -4,3 +4,7 @@ pointer-events: all; padding-left: $euiSizeM; } + +.mapAttributionControl__fullScreen { + margin-left: $euiSizeXXL * 4; +} diff --git a/x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/attribution_control/index.js b/x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/attribution_control/index.js index e73a51ffa2ced..8bad536b39245 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/attribution_control/index.js +++ b/x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/attribution_control/index.js @@ -7,10 +7,12 @@ import { connect } from 'react-redux'; import { AttributionControl } from './view'; import { getLayerList } from '../../../selectors/map_selectors'; +import { getIsFullScreen } from '../../../selectors/ui_selectors'; function mapStateToProps(state = {}) { return { layerList: getLayerList(state), + isFullScreen: getIsFullScreen(state), }; } diff --git a/x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/attribution_control/view.js b/x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/attribution_control/view.js index 161b5b81c1255..8f11d1b23376c 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/attribution_control/view.js +++ b/x-pack/legacy/plugins/maps/public/connected_components/widget_overlay/attribution_control/view.js @@ -7,6 +7,7 @@ import React, { Fragment } from 'react'; import _ from 'lodash'; import { EuiText, EuiLink } from '@elastic/eui'; +import classNames from 'classnames'; export class AttributionControl extends React.Component { state = { @@ -86,7 +87,11 @@ export class AttributionControl extends React.Component { return null; } return ( -
+
{this._renderAttributions()} From 1c718d676049d77168b5c326a4a92543ce158e8d Mon Sep 17 00:00:00 2001 From: Josh Dover Date: Wed, 8 Apr 2020 11:30:12 -0600 Subject: [PATCH 23/40] Add --filter option to API docs script (#62888) --- src/dev/run_check_published_api_changes.ts | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/dev/run_check_published_api_changes.ts b/src/dev/run_check_published_api_changes.ts index 8bb3fb20cea8b..ba3cd1280f34b 100644 --- a/src/dev/run_check_published_api_changes.ts +++ b/src/dev/run_check_published_api_changes.ts @@ -163,6 +163,7 @@ interface Options { accept: boolean; docs: boolean; help: boolean; + filter: string; } async function run( @@ -205,6 +206,7 @@ async function run( const extraFlags: string[] = []; const opts = (getopts(process.argv.slice(2), { boolean: ['accept', 'docs', 'help'], + string: ['filter'], default: { project: undefined, }, @@ -222,6 +224,8 @@ async function run( opts.help = true; } + const folders = ['core/public', 'core/server', 'plugins/data/server', 'plugins/data/public']; + if (opts.help) { process.stdout.write( dedent(chalk` @@ -240,9 +244,13 @@ async function run( {dim # Checks for and automatically accepts and updates documentation for any changes to the Kibana Core API} {dim $} node scripts/check_published_api_changes --accept + {dim # Only checks the core/public directory} + {dim $} node scripts/check_published_api_changes --filter=core/public + Options: --accept {dim Accepts all changes by updating the API Review files and documentation} --docs {dim Updates the Core API documentation} + --only {dim RegExp that folder names must match, folders: [${folders.join(', ')}]} --help {dim Show this message} `) ); @@ -258,9 +266,11 @@ async function run( return false; } - const folders = ['core/public', 'core/server', 'plugins/data/server', 'plugins/data/public']; - - const results = await Promise.all(folders.map(folder => run(folder, { log, opts }))); + const results = await Promise.all( + folders + .filter(folder => (opts.filter.length ? folder.match(opts.filter) : true)) + .map(folder => run(folder, { log, opts })) + ); if (results.find(r => r === false) !== undefined) { process.exitCode = 1; From cbe479b8bd1297a5f54b2b9a3f8ea9f480cbb713 Mon Sep 17 00:00:00 2001 From: Zacqary Adam Xeper Date: Wed, 8 Apr 2020 12:39:59 -0500 Subject: [PATCH 24/40] [Metrics UI] Invalidate non-count alerts which have no metrics (#62837) --- .../public/components/alerting/metrics/validation.tsx | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/x-pack/plugins/infra/public/components/alerting/metrics/validation.tsx b/x-pack/plugins/infra/public/components/alerting/metrics/validation.tsx index 55365c3d4c2ba..d84e46d08a287 100644 --- a/x-pack/plugins/infra/public/components/alerting/metrics/validation.tsx +++ b/x-pack/plugins/infra/public/components/alerting/metrics/validation.tsx @@ -23,6 +23,7 @@ export function validateMetricThreshold({ timeWindowSize: string[]; threshold0: string[]; threshold1: string[]; + metric: string[]; }; } = {}; validationResult.errors = errors; @@ -41,6 +42,7 @@ export function validateMetricThreshold({ timeWindowSize: [], threshold0: [], threshold1: [], + metric: [], }; if (!c.aggType) { errors[id].aggField.push( @@ -73,6 +75,14 @@ export function validateMetricThreshold({ }) ); } + + if (!c.metric && c.aggType !== 'count') { + errors[id].metric.push( + i18n.translate('xpack.infra.metrics.alertFlyout.error.metricRequired', { + defaultMessage: 'Metric is required.', + }) + ); + } }); return validationResult; From 941a4879ae2072344cc3be5846c47c8e2340d153 Mon Sep 17 00:00:00 2001 From: Zacqary Adam Xeper Date: Wed, 8 Apr 2020 12:40:27 -0500 Subject: [PATCH 25/40] [Alerting] Fix validation support for nested IErrorObjects (#62833) * [Alerting] Add validation support for nested IErrorObjects * Typecheck fix * Fix recursion crash when errors are strings * Typecheck fix --- .../public/application/sections/alert_form/alert_add.tsx | 9 ++++++++- .../public/common/expression_items/of.tsx | 3 ++- .../public/common/expression_items/threshold.tsx | 3 ++- x-pack/plugins/triggers_actions_ui/public/types.ts | 2 +- 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_add.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_add.tsx index e44e20751b315..e025248fad52e 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_add.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_add.tsx @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ import React, { useCallback, useReducer, useState } from 'react'; +import { isObject } from 'lodash'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiTitle, @@ -83,7 +84,7 @@ export const AlertAdd = ({ ...(alertType ? alertType.validate(alert.params).errors : []), ...validateBaseProperties(alert).errors, } as IErrorObject; - const hasErrors = !!Object.keys(errors).find(errorKey => errors[errorKey].length >= 1); + const hasErrors = parseErrors(errors); const actionsErrors: Array<{ errors: IErrorObject; @@ -213,3 +214,9 @@ export const AlertAdd = ({ ); }; + +const parseErrors: (errors: IErrorObject) => boolean = errors => + !!Object.values(errors).find(errorList => { + if (isObject(errorList)) return parseErrors(errorList as IErrorObject); + return errorList.length >= 1; + }); diff --git a/x-pack/plugins/triggers_actions_ui/public/common/expression_items/of.tsx b/x-pack/plugins/triggers_actions_ui/public/common/expression_items/of.tsx index d399f6136690b..3de0a99ccbbd9 100644 --- a/x-pack/plugins/triggers_actions_ui/public/common/expression_items/of.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/common/expression_items/of.tsx @@ -17,13 +17,14 @@ import { } from '@elastic/eui'; import { builtInAggregationTypes } from '../constants'; import { AggregationType } from '../types'; +import { IErrorObject } from '../../types'; import { ClosablePopoverTitle } from './components'; import './of.scss'; interface OfExpressionProps { aggType: string; aggField?: string; - errors: { [key: string]: string[] }; + errors: IErrorObject; onChangeSelectedAggField: (selectedAggType?: string) => void; fields: Record; customAggTypesOptions?: { diff --git a/x-pack/plugins/triggers_actions_ui/public/common/expression_items/threshold.tsx b/x-pack/plugins/triggers_actions_ui/public/common/expression_items/threshold.tsx index fb3ff9ceb0926..99dd7b63383fb 100644 --- a/x-pack/plugins/triggers_actions_ui/public/common/expression_items/threshold.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/common/expression_items/threshold.tsx @@ -18,11 +18,12 @@ import { } from '@elastic/eui'; import { builtInComparators } from '../constants'; import { Comparator } from '../types'; +import { IErrorObject } from '../../types'; import { ClosablePopoverTitle } from './components'; interface ThresholdExpressionProps { thresholdComparator: string; - errors: { [key: string]: string[] }; + errors: IErrorObject; onChangeSelectedThresholdComparator: (selectedThresholdComparator?: string) => void; onChangeSelectedThreshold: (selectedThreshold?: number[]) => void; customComparators?: { diff --git a/x-pack/plugins/triggers_actions_ui/public/types.ts b/x-pack/plugins/triggers_actions_ui/public/types.ts index 31c77833cc0e8..7f78d327d0122 100644 --- a/x-pack/plugins/triggers_actions_ui/public/types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/types.ts @@ -112,5 +112,5 @@ export interface AlertTypeModel { } export interface IErrorObject { - [key: string]: string[]; + [key: string]: string | string[] | IErrorObject; } From d4f2bd744dc64eb530277927c67807c2a5fb9ba2 Mon Sep 17 00:00:00 2001 From: Jen Huang Date: Wed, 8 Apr 2020 10:45:15 -0700 Subject: [PATCH 26/40] Exclude disabled datasources and streams from agent config (#62869) --- .../datasource_to_agent_datasource.test.ts | 42 ++++++++++++++++++- .../datasource_to_agent_datasource.ts | 18 ++++---- .../server/services/agent_config.ts | 6 +-- 3 files changed, 53 insertions(+), 13 deletions(-) diff --git a/x-pack/plugins/ingest_manager/common/services/datasource_to_agent_datasource.test.ts b/x-pack/plugins/ingest_manager/common/services/datasource_to_agent_datasource.test.ts index ab039be8e7c22..b897c03e89f82 100644 --- a/x-pack/plugins/ingest_manager/common/services/datasource_to_agent_datasource.test.ts +++ b/x-pack/plugins/ingest_manager/common/services/datasource_to_agent_datasource.test.ts @@ -41,7 +41,7 @@ describe('Ingest Manager - storedDatasourceToAgentDatasource', () => { }, { id: 'test-logs-bar', - enabled: false, + enabled: true, dataset: 'bar', config: { barVar: { value: 'bar-value' }, @@ -119,7 +119,7 @@ describe('Ingest Manager - storedDatasourceToAgentDatasource', () => { }, { id: 'test-logs-bar', - enabled: false, + enabled: true, dataset: 'bar', barVar: 'bar-value', barVar2: [1, 2], @@ -140,6 +140,44 @@ describe('Ingest Manager - storedDatasourceToAgentDatasource', () => { }); }); + it('returns agent datasource config without disabled streams', () => { + expect( + storedDatasourceToAgentDatasource({ + ...mockDatasource, + inputs: [ + { + ...mockInput, + streams: [{ ...mockInput.streams[0] }, { ...mockInput.streams[1], enabled: false }], + }, + ], + }) + ).toEqual({ + id: 'mock-datasource', + namespace: 'default', + enabled: true, + use_output: 'default', + inputs: [ + { + type: 'test-logs', + enabled: true, + inputVar: 'input-value', + inputVar3: { + testField: 'test', + }, + streams: [ + { + id: 'test-logs-foo', + enabled: true, + dataset: 'foo', + fooVar: 'foo-value', + fooVar2: [1, 2], + }, + ], + }, + ], + }); + }); + it('returns agent datasource config without disabled inputs', () => { expect( storedDatasourceToAgentDatasource({ diff --git a/x-pack/plugins/ingest_manager/common/services/datasource_to_agent_datasource.ts b/x-pack/plugins/ingest_manager/common/services/datasource_to_agent_datasource.ts index f58eaacb7be67..20bbbec8919d6 100644 --- a/x-pack/plugins/ingest_manager/common/services/datasource_to_agent_datasource.ts +++ b/x-pack/plugins/ingest_manager/common/services/datasource_to_agent_datasource.ts @@ -51,14 +51,16 @@ export const storedDatasourceToAgentDatasource = ( const fullInput = { ...input, ...Object.entries(input.config || {}).reduce(configReducer, {}), - streams: input.streams.map(stream => { - const fullStream = { - ...stream, - ...Object.entries(stream.config || {}).reduce(configReducer, {}), - }; - delete fullStream.config; - return fullStream; - }), + streams: input.streams + .filter(stream => stream.enabled) + .map(stream => { + const fullStream = { + ...stream, + ...Object.entries(stream.config || {}).reduce(configReducer, {}), + }; + delete fullStream.config; + return fullStream; + }), }; delete fullInput.config; return fullInput; diff --git a/x-pack/plugins/ingest_manager/server/services/agent_config.ts b/x-pack/plugins/ingest_manager/server/services/agent_config.ts index a941494072ae3..309ddca3784c2 100644 --- a/x-pack/plugins/ingest_manager/server/services/agent_config.ts +++ b/x-pack/plugins/ingest_manager/server/services/agent_config.ts @@ -319,9 +319,9 @@ class AgentConfigService { return outputs; }, {} as FullAgentConfig['outputs']), }, - datasources: (config.datasources as Datasource[]).map(ds => - storedDatasourceToAgentDatasource(ds) - ), + datasources: (config.datasources as Datasource[]) + .filter(datasource => datasource.enabled) + .map(ds => storedDatasourceToAgentDatasource(ds)), revision: config.revision, }; From 184f59447bfb1cb5ffc83e0e8d1df8bfe282f9d8 Mon Sep 17 00:00:00 2001 From: Oliver Gupte Date: Wed, 8 Apr 2020 11:13:39 -0700 Subject: [PATCH 27/40] [APM] Service map - fixes layout issues for maps with no rum services (#62887) * Closes #62878 in Service Maps by improving the selection algorithm for root nodes * Fixes some latent centering issues when navigating in the service map. * Removes unused imports * Added layoutstopDelayTimeout to cleanup step --- .../components/app/ServiceMap/Cytoscape.tsx | 41 +++++++++++++------ 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/Cytoscape.tsx b/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/Cytoscape.tsx index 21bedc204f48b..e4b656ae8160d 100644 --- a/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/Cytoscape.tsx +++ b/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/Cytoscape.tsx @@ -14,8 +14,6 @@ import React, { useState } from 'react'; import { debounce } from 'lodash'; -import { isRumAgentName } from '../../../../../../../plugins/apm/common/agent_name'; -import { AGENT_NAME } from '../../../../../../../plugins/apm/common/elasticsearch_fieldnames'; import { animationOptions, cytoscapeOptions, @@ -96,10 +94,15 @@ function getLayoutOptions( } function selectRoots(cy: cytoscape.Core): string[] { - const nodes = cy.nodes(); - const roots = nodes.roots(); - const rumNodes = nodes.filter(node => isRumAgentName(node.data(AGENT_NAME))); - return rumNodes.union(roots).map(node => node.id()); + const bfs = cy.elements().bfs({ + roots: cy.elements().leaves() + }); + const furthestNodeFromLeaves = bfs.path.last(); + return cy + .elements() + .roots() + .union(furthestNodeFromLeaves) + .map(el => el.id()); } export function Cytoscape({ @@ -168,15 +171,26 @@ export function Cytoscape({ layout.run(); } }; + let layoutstopDelayTimeout: NodeJS.Timeout; const layoutstopHandler: cytoscape.EventHandler = event => { - event.cy.animate({ - ...animationOptions, - center: { - eles: serviceName - ? event.cy.getElementById(serviceName) - : event.cy.collection() + // This 0ms timer is necessary to prevent a race condition + // between the layout finishing rendering and viewport centering + layoutstopDelayTimeout = setTimeout(() => { + if (serviceName) { + event.cy.animate({ + ...animationOptions, + fit: { + eles: event.cy.elements(), + padding: nodeHeight + }, + center: { + eles: event.cy.getElementById(serviceName) + } + }); + } else { + event.cy.fit(undefined, nodeHeight); } - }); + }, 0); }; // debounce hover tracking so it doesn't spam telemetry with redundant events const trackNodeEdgeHover = debounce( @@ -231,6 +245,7 @@ export function Cytoscape({ cy.removeListener('select', 'node', selectHandler); cy.removeListener('unselect', 'node', unselectHandler); } + clearTimeout(layoutstopDelayTimeout); }; }, [cy, height, serviceName, trackApmEvent, width]); From 369ddff95192373923fb5323ef06b70868303c4c Mon Sep 17 00:00:00 2001 From: Spencer Date: Wed, 8 Apr 2020 12:15:48 -0700 Subject: [PATCH 28/40] [kbn/optimizer] link to kibanaReact/kibanaUtils plugins (#62720) * [kbn/optimizer] link to data/kibanaReact/kibanaUtils plugins * depend on normalize-path package * typos * avoid loading kibanaUtils and kibanaReact from urls * update types and tests, now that whole plugin is exported to window * update snapshot, removed export of `plugins` property * fix condition, ignore things NOT in data/react/utils * make es_ui_shared a "static bundle" too * move kibana_utils/common usage to /public * convert some more /common usage to /public * use async-download/ordered-execution for bootstrap script * fix typo * remove kibanaUtils bundle * remove kibanaReact bundle * Revert "remove kibanaReact bundle" This reverts commit f14e9ee604ae8f0bb664a04c6966e337254d2659. * Revert "remove kibanaUtils bundle" This reverts commit a64b2a7f647f44f6d1941dba4ba39076ce5d74d9. * stop linking to the data plugin * add comment pointing to async-download info Co-authored-by: spalger Co-authored-by: Elastic Machine --- packages/kbn-optimizer/package.json | 1 + .../basic_optimization.test.ts.snap | 4 +- .../src/worker/webpack.config.ts | 68 ++++++++++++++++-- packages/kbn-ui-shared-deps/polyfills.js | 7 ++ src/core/public/plugins/plugin_loader.test.ts | 2 +- src/core/public/plugins/plugin_loader.ts | 33 ++++++--- .../public/input_control_vis_type.ts | 2 +- .../kibana/public/discover/kibana_services.ts | 4 +- .../vis_type_metric/public/services.ts | 2 +- .../vis_type_table/public/services.ts | 2 +- .../vis_type_tagcloud/public/services.ts | 2 +- .../public/metrics_type.ts | 2 +- .../public/__mocks__/services.ts | 2 +- .../vis_type_vega/public/vega_type.ts | 2 +- .../vis_type_vislib/public/services.ts | 2 +- .../ui/ui_render/bootstrap/template.js.hbs | 69 ++++++++----------- src/plugins/discover/public/services.ts | 2 +- .../embeddable_action_storage.test.ts | 2 +- src/plugins/es_ui_shared/kibana.json | 5 ++ src/plugins/es_ui_shared/public/index.ts | 8 +++ src/plugins/kibana_react/kibana.json | 5 ++ .../public/adapters/react_to_ui_component.ts | 2 +- .../adapters/ui_to_react_component.test.tsx | 2 +- .../public/adapters/ui_to_react_component.ts | 2 +- src/plugins/kibana_react/public/index.ts | 8 +++ src/plugins/kibana_utils/kibana.json | 5 ++ src/plugins/kibana_utils/public/index.ts | 11 ++- .../ui_actions/public/actions/action.ts | 2 +- .../public/actions/action_definition.ts | 2 +- 29 files changed, 182 insertions(+), 78 deletions(-) create mode 100644 src/plugins/es_ui_shared/kibana.json create mode 100644 src/plugins/kibana_react/kibana.json create mode 100644 src/plugins/kibana_utils/kibana.json diff --git a/packages/kbn-optimizer/package.json b/packages/kbn-optimizer/package.json index b648004760d7c..b3e5a8c518682 100644 --- a/packages/kbn-optimizer/package.json +++ b/packages/kbn-optimizer/package.json @@ -32,6 +32,7 @@ "json-stable-stringify": "^1.0.1", "loader-utils": "^1.2.3", "node-sass": "^4.13.0", + "normalize-path": "^3.0.0", "postcss-loader": "^3.0.0", "raw-loader": "^3.1.0", "resolve-url-loader": "^3.1.1", diff --git a/packages/kbn-optimizer/src/integration_tests/__snapshots__/basic_optimization.test.ts.snap b/packages/kbn-optimizer/src/integration_tests/__snapshots__/basic_optimization.test.ts.snap index d52d89eebe2f1..4b4bb1282d939 100644 --- a/packages/kbn-optimizer/src/integration_tests/__snapshots__/basic_optimization.test.ts.snap +++ b/packages/kbn-optimizer/src/integration_tests/__snapshots__/basic_optimization.test.ts.snap @@ -57,6 +57,6 @@ OptimizerConfig { } `; -exports[`builds expected bundles, saves bundle counts to metadata: bar bundle 1`] = `"var __kbnBundles__=typeof __kbnBundles__===\\"object\\"?__kbnBundles__:{};__kbnBundles__[\\"plugin/bar\\"]=function(modules){function webpackJsonpCallback(data){var chunkIds=data[0];var moreModules=data[1];var moduleId,chunkId,i=0,resolves=[];for(;i bundle.id === p.id)) { + return; + } + + // ignore requests that don't include a /data/public, /kibana_react/public, or + // /kibana_utils/public segment as a cheap way to avoid doing path resolution + // for paths that couldn't possibly resolve to what we're looking for + const reqToStaticBundle = STATIC_BUNDLE_PLUGINS.some(p => + request.includes(`/${p.dirname}/public`) + ); + if (!reqToStaticBundle) { + return; + } + + // determine the most acurate resolution string we can without running full resolution + const rootRelative = normalizePath( + Path.relative(bundle.sourceRoot, Path.resolve(context, request)) + ); + for (const { id, dirname } of STATIC_BUNDLE_PLUGINS) { + if (rootRelative === `src/plugins/${dirname}/public`) { + return `__kbnBundles__['plugin/${id}']`; + } + } + + // import doesn't match a root public import + return undefined; +} + export function getWebpackConfig(bundle: Bundle, worker: WorkerConfig) { const commonConfig: webpack.Configuration = { node: { fs: 'empty' }, @@ -63,7 +117,6 @@ export function getWebpackConfig(bundle: Bundle, worker: WorkerConfig) { // When the entry point is loaded, assign it's exported `plugin` // value to a key on the global `__kbnBundles__` object. library: ['__kbnBundles__', `plugin/${bundle.id}`], - libraryExport: 'plugin', } : {}), }, @@ -72,9 +125,16 @@ export function getWebpackConfig(bundle: Bundle, worker: WorkerConfig) { noEmitOnErrors: true, }, - externals: { - ...UiSharedDeps.externals, - }, + externals: [ + UiSharedDeps.externals, + function(context, request, cb) { + try { + cb(undefined, dynamicExternals(bundle, context, request)); + } catch (error) { + cb(error, undefined); + } + }, + ], plugins: [new CleanWebpackPlugin(), new DisallowedSyntaxPlugin()], diff --git a/packages/kbn-ui-shared-deps/polyfills.js b/packages/kbn-ui-shared-deps/polyfills.js index d2305d643e4d2..1f1392b02baff 100644 --- a/packages/kbn-ui-shared-deps/polyfills.js +++ b/packages/kbn-ui-shared-deps/polyfills.js @@ -20,6 +20,13 @@ require('core-js/stable'); require('regenerator-runtime/runtime'); require('custom-event-polyfill'); + +if (typeof window.Event === 'object') { + // IE11 doesn't support unknown event types, required by react-use + // https://github.com/streamich/react-use/issues/73 + window.Event = CustomEvent; +} + require('whatwg-fetch'); require('abortcontroller-polyfill/dist/polyfill-patch-fetch'); require('./vendor/childnode_remove_polyfill'); diff --git a/src/core/public/plugins/plugin_loader.test.ts b/src/core/public/plugins/plugin_loader.test.ts index e5cbffc3e2d94..b4e2c3095f14a 100644 --- a/src/core/public/plugins/plugin_loader.test.ts +++ b/src/core/public/plugins/plugin_loader.test.ts @@ -71,7 +71,7 @@ test('`loadPluginBundles` creates a script tag and loads initializer', async () // Setup a fake initializer as if a plugin bundle had actually been loaded. const fakeInitializer = jest.fn(); - coreWindow.__kbnBundles__['plugin/plugin-a'] = fakeInitializer; + coreWindow.__kbnBundles__['plugin/plugin-a'] = { plugin: fakeInitializer }; // Call the onload callback fakeScriptTag.onload(); await expect(loadPromise).resolves.toEqual(fakeInitializer); diff --git a/src/core/public/plugins/plugin_loader.ts b/src/core/public/plugins/plugin_loader.ts index 63aba0dde2af8..bf7711055e97b 100644 --- a/src/core/public/plugins/plugin_loader.ts +++ b/src/core/public/plugins/plugin_loader.ts @@ -32,7 +32,7 @@ export type UnknownPluginInitializer = PluginInitializer new Promise>( (resolve, reject) => { - const script = document.createElement('script'); const coreWindow = (window as unknown) as CoreWindow; + const exportId = `plugin/${pluginName}`; + + const readPluginExport = () => { + const PluginExport: any = coreWindow.__kbnBundles__[exportId]; + if (typeof PluginExport?.plugin !== 'function') { + reject( + new Error(`Definition of plugin "${pluginName}" should be a function (${bundlePath}).`) + ); + } else { + resolve( + PluginExport.plugin as PluginInitializer + ); + } + }; + if (coreWindow.__kbnBundles__[exportId]) { + readPluginExport(); + return; + } + + const script = document.createElement('script'); // Assumes that all plugin bundles get put into the bundles/plugins subdirectory const bundlePath = addBasePath(`/bundles/plugin/${pluginName}/${pluginName}.plugin.js`); script.setAttribute('src', bundlePath); @@ -89,15 +108,7 @@ export const loadPluginBundle: LoadPluginBundle = < // Wire up resolve and reject script.onload = () => { cleanupTag(); - - const initializer = coreWindow.__kbnBundles__[`plugin/${pluginName}`]; - if (!initializer || typeof initializer !== 'function') { - reject( - new Error(`Definition of plugin "${pluginName}" should be a function (${bundlePath}).`) - ); - } else { - resolve(initializer as PluginInitializer); - } + readPluginExport(); }; script.onerror = () => { diff --git a/src/legacy/core_plugins/input_control_vis/public/input_control_vis_type.ts b/src/legacy/core_plugins/input_control_vis/public/input_control_vis_type.ts index 023e6ebb7125c..badea68eec19f 100644 --- a/src/legacy/core_plugins/input_control_vis/public/input_control_vis_type.ts +++ b/src/legacy/core_plugins/input_control_vis/public/input_control_vis_type.ts @@ -23,7 +23,7 @@ import { createInputControlVisController } from './vis_controller'; import { getControlsTab } from './components/editor/controls_tab'; import { OptionsTab } from './components/editor/options_tab'; import { InputControlVisDependencies } from './plugin'; -import { defaultFeedbackMessage } from '../../../../plugins/kibana_utils/common'; +import { defaultFeedbackMessage } from '../../../../plugins/kibana_utils/public'; export function createInputControlVisTypeDefinition(deps: InputControlVisDependencies) { const InputControlVisController = createInputControlVisController(deps); diff --git a/src/legacy/core_plugins/kibana/public/discover/kibana_services.ts b/src/legacy/core_plugins/kibana/public/discover/kibana_services.ts index e6421142f6666..98679a8f24d16 100644 --- a/src/legacy/core_plugins/kibana/public/discover/kibana_services.ts +++ b/src/legacy/core_plugins/kibana/public/discover/kibana_services.ts @@ -17,6 +17,8 @@ * under the License. */ import { DiscoverServices } from './build_services'; +import { createGetterSetter } from '../../../../../plugins/kibana_utils/public'; +import { search } from '../../../../../plugins/data/public'; let angularModule: any = null; let services: DiscoverServices | null = null; @@ -50,8 +52,6 @@ export const [getUrlTracker, setUrlTracker] = createGetterSetter<{ setTrackedUrl: (url: string) => void; }>('urlTracker'); -import { search } from '../../../../../plugins/data/public'; -import { createGetterSetter } from '../../../../../plugins/kibana_utils/common'; export const { getRequestInspectorStats, getResponseInspectorStats, tabifyAggResponse } = search; export { unhashUrl, diff --git a/src/legacy/core_plugins/vis_type_metric/public/services.ts b/src/legacy/core_plugins/vis_type_metric/public/services.ts index 5af11bc7f0b03..b303ccd5aeed2 100644 --- a/src/legacy/core_plugins/vis_type_metric/public/services.ts +++ b/src/legacy/core_plugins/vis_type_metric/public/services.ts @@ -17,7 +17,7 @@ * under the License. */ -import { createGetterSetter } from '../../../../plugins/kibana_utils/common'; +import { createGetterSetter } from '../../../../plugins/kibana_utils/public'; import { DataPublicPluginStart } from '../../../../plugins/data/public'; export const [getFormatService, setFormatService] = createGetterSetter< diff --git a/src/legacy/core_plugins/vis_type_table/public/services.ts b/src/legacy/core_plugins/vis_type_table/public/services.ts index 08efed733cafe..b4b491ac7a555 100644 --- a/src/legacy/core_plugins/vis_type_table/public/services.ts +++ b/src/legacy/core_plugins/vis_type_table/public/services.ts @@ -17,7 +17,7 @@ * under the License. */ -import { createGetterSetter } from '../../../../plugins/kibana_utils/common'; +import { createGetterSetter } from '../../../../plugins/kibana_utils/public'; import { DataPublicPluginStart } from '../../../../plugins/data/public'; export const [getFormatService, setFormatService] = createGetterSetter< diff --git a/src/legacy/core_plugins/vis_type_tagcloud/public/services.ts b/src/legacy/core_plugins/vis_type_tagcloud/public/services.ts index fef46282eb8dd..272bed3e91a08 100644 --- a/src/legacy/core_plugins/vis_type_tagcloud/public/services.ts +++ b/src/legacy/core_plugins/vis_type_tagcloud/public/services.ts @@ -17,7 +17,7 @@ * under the License. */ -import { createGetterSetter } from '../../../../plugins/kibana_utils/common'; +import { createGetterSetter } from '../../../../plugins/kibana_utils/public'; import { DataPublicPluginStart } from '../../../../plugins/data/public'; export const [getFormatService, setFormatService] = createGetterSetter< diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/metrics_type.ts b/src/legacy/core_plugins/vis_type_timeseries/public/metrics_type.ts index 30c62d778933b..1db35c406eb13 100644 --- a/src/legacy/core_plugins/vis_type_timeseries/public/metrics_type.ts +++ b/src/legacy/core_plugins/vis_type_timeseries/public/metrics_type.ts @@ -25,7 +25,7 @@ import { metricsRequestHandler } from './request_handler'; import { EditorController } from './editor_controller'; // @ts-ignore import { PANEL_TYPES } from '../../../../plugins/vis_type_timeseries/common/panel_types'; -import { defaultFeedbackMessage } from '../../../../plugins/kibana_utils/common'; +import { defaultFeedbackMessage } from '../../../../plugins/kibana_utils/public'; export const metricsVisDefinition = { name: 'metrics', diff --git a/src/legacy/core_plugins/vis_type_vega/public/__mocks__/services.ts b/src/legacy/core_plugins/vis_type_vega/public/__mocks__/services.ts index 64a9aaaf3b7a6..b2f3e5b2241e6 100644 --- a/src/legacy/core_plugins/vis_type_vega/public/__mocks__/services.ts +++ b/src/legacy/core_plugins/vis_type_vega/public/__mocks__/services.ts @@ -17,7 +17,7 @@ * under the License. */ -import { createGetterSetter } from '../../../../../plugins/kibana_utils/common'; +import { createGetterSetter } from '../../../../../plugins/kibana_utils/public'; import { DataPublicPluginStart } from '../../../../../plugins/data/public'; import { IUiSettingsClient, NotificationsStart, SavedObjectsStart } from 'kibana/public'; import { dataPluginMock } from '../../../../../plugins/data/public/mocks'; diff --git a/src/legacy/core_plugins/vis_type_vega/public/vega_type.ts b/src/legacy/core_plugins/vis_type_vega/public/vega_type.ts index 5d9ed5c8df91c..f56d7682efc6f 100644 --- a/src/legacy/core_plugins/vis_type_vega/public/vega_type.ts +++ b/src/legacy/core_plugins/vis_type_vega/public/vega_type.ts @@ -21,7 +21,7 @@ import { i18n } from '@kbn/i18n'; import { DefaultEditorSize } from '../../../../plugins/vis_default_editor/public'; import { VegaVisualizationDependencies } from './plugin'; import { VegaVisEditor } from './components'; -import { defaultFeedbackMessage } from '../../../../plugins/kibana_utils/common'; +import { defaultFeedbackMessage } from '../../../../plugins/kibana_utils/public'; import { createVegaRequestHandler } from './vega_request_handler'; // @ts-ignore diff --git a/src/legacy/core_plugins/vis_type_vislib/public/services.ts b/src/legacy/core_plugins/vis_type_vislib/public/services.ts index da50e227d84d2..0d6b1b5e8de58 100644 --- a/src/legacy/core_plugins/vis_type_vislib/public/services.ts +++ b/src/legacy/core_plugins/vis_type_vislib/public/services.ts @@ -17,7 +17,7 @@ * under the License. */ -import { createGetterSetter } from '../../../../plugins/kibana_utils/common'; +import { createGetterSetter } from '../../../../plugins/kibana_utils/public'; import { DataPublicPluginStart } from '../../../../plugins/data/public'; export const [getDataActions, setDataActions] = createGetterSetter< diff --git a/src/legacy/ui/ui_render/bootstrap/template.js.hbs b/src/legacy/ui/ui_render/bootstrap/template.js.hbs index ad4aa97d8ea7a..1093153edbbf7 100644 --- a/src/legacy/ui/ui_render/bootstrap/template.js.hbs +++ b/src/legacy/ui/ui_render/bootstrap/template.js.hbs @@ -30,33 +30,27 @@ if (window.__kbnStrictCsp__ && window.__kbnCspNotEnforced__) { function loadStyleSheet(url, cb) { var dom = document.createElement('link'); + dom.rel = 'stylesheet'; + dom.type = 'text/css'; + dom.href = url; dom.addEventListener('error', failure); - dom.setAttribute('rel', 'stylesheet'); - dom.setAttribute('type', 'text/css'); - dom.setAttribute('href', url); dom.addEventListener('load', cb); document.head.appendChild(dom); } function loadScript(url, cb) { var dom = document.createElement('script'); - dom.setAttribute('async', ''); + {{!-- NOTE: async = false is used to trigger async-download/ordered-execution as outlined here: https://www.html5rocks.com/en/tutorials/speed/script-loading/ --}} + dom.async = false; + dom.src = url; dom.addEventListener('error', failure); - dom.setAttribute('src', url); dom.addEventListener('load', cb); document.head.appendChild(dom); } - function load(urlSet, cb) { - if (urlSet.deps) { - load({ urls: urlSet.deps }, function () { - load({ urls: urlSet.urls }, cb); - }); - return; - } - - var pending = urlSet.urls.length; - urlSet.urls.forEach(function (url) { + function load(urls, cb) { + var pending = urls.length; + urls.forEach(function (url) { var innerCb = function () { pending = pending - 1; if (pending === 0 && typeof cb === 'function') { @@ -74,36 +68,27 @@ if (window.__kbnStrictCsp__ && window.__kbnCspNotEnforced__) { }); } - load({ - deps: [ + load([ {{#each sharedJsDepFilenames}} '{{../regularBundlePath}}/kbn-ui-shared-deps/{{this}}', {{/each}} - ], - urls: [ - { - deps: [ - '{{regularBundlePath}}/kbn-ui-shared-deps/{{sharedJsFilename}}', - { - deps: [ - '{{dllBundlePath}}/vendors_runtime.bundle.dll.js' - ], - urls: [ - {{#each dllJsChunks}} - '{{this}}', - {{/each}} - ] - }, - '{{regularBundlePath}}/commons.bundle.js', - ], - urls: [ - '{{regularBundlePath}}/{{appId}}.bundle.js', - {{#each styleSheetPaths}} - '{{this}}', - {{/each}} - ] - } - ] + '{{regularBundlePath}}/kbn-ui-shared-deps/{{sharedJsFilename}}', + '{{dllBundlePath}}/vendors_runtime.bundle.dll.js', + {{#each dllJsChunks}} + '{{this}}', + {{/each}} + '{{regularBundlePath}}/commons.bundle.js', + {{!-- '{{regularBundlePath}}/plugin/data/data.plugin.js', --}} + '{{regularBundlePath}}/plugin/kibanaUtils/kibanaUtils.plugin.js', + '{{regularBundlePath}}/plugin/esUiShared/esUiShared.plugin.js', + '{{regularBundlePath}}/plugin/kibanaReact/kibanaReact.plugin.js' + ], function () { + load([ + '{{regularBundlePath}}/{{appId}}.bundle.js', + {{#each styleSheetPaths}} + '{{this}}', + {{/each}} + ]) }); }; } diff --git a/src/plugins/discover/public/services.ts b/src/plugins/discover/public/services.ts index 3a28759d82b71..37e2144800ea1 100644 --- a/src/plugins/discover/public/services.ts +++ b/src/plugins/discover/public/services.ts @@ -17,7 +17,7 @@ * under the License. */ -import { createGetterSetter } from '../../kibana_utils/common'; +import { createGetterSetter } from '../../kibana_utils/public'; import { DocViewsRegistry } from './doc_views/doc_views_registry'; export const [getDocViewsRegistry, setDocViewsRegistry] = createGetterSetter( diff --git a/src/plugins/embeddable/public/lib/embeddables/embeddable_action_storage.test.ts b/src/plugins/embeddable/public/lib/embeddables/embeddable_action_storage.test.ts index 56facc37fc666..ddd84b0544345 100644 --- a/src/plugins/embeddable/public/lib/embeddables/embeddable_action_storage.test.ts +++ b/src/plugins/embeddable/public/lib/embeddables/embeddable_action_storage.test.ts @@ -21,7 +21,7 @@ import { Embeddable } from './embeddable'; import { EmbeddableInput } from './i_embeddable'; import { ViewMode } from '../types'; import { EmbeddableActionStorage, SerializedEvent } from './embeddable_action_storage'; -import { of } from '../../../../kibana_utils/common'; +import { of } from '../../../../kibana_utils/public'; class TestEmbeddable extends Embeddable { public readonly type = 'test'; diff --git a/src/plugins/es_ui_shared/kibana.json b/src/plugins/es_ui_shared/kibana.json new file mode 100644 index 0000000000000..5a3db3b344090 --- /dev/null +++ b/src/plugins/es_ui_shared/kibana.json @@ -0,0 +1,5 @@ +{ + "id": "esUiShared", + "version": "kibana", + "ui": true +} diff --git a/src/plugins/es_ui_shared/public/index.ts b/src/plugins/es_ui_shared/public/index.ts index 944b800c66a28..6db6248f4c68f 100644 --- a/src/plugins/es_ui_shared/public/index.ts +++ b/src/plugins/es_ui_shared/public/index.ts @@ -35,3 +35,11 @@ export { export { indices } from './indices'; export { useUIAceKeyboardMode } from './use_ui_ace_keyboard_mode'; + +/** dummy plugin, we just want esUiShared to have its own bundle */ +export function plugin() { + return new (class EsUiSharedPlugin { + setup() {} + start() {} + })(); +} diff --git a/src/plugins/kibana_react/kibana.json b/src/plugins/kibana_react/kibana.json new file mode 100644 index 0000000000000..0add1bee84ae0 --- /dev/null +++ b/src/plugins/kibana_react/kibana.json @@ -0,0 +1,5 @@ +{ + "id": "kibanaReact", + "version": "kibana", + "ui": true +} diff --git a/src/plugins/kibana_react/public/adapters/react_to_ui_component.ts b/src/plugins/kibana_react/public/adapters/react_to_ui_component.ts index b4007b30cf8ca..21bba92ada4c1 100644 --- a/src/plugins/kibana_react/public/adapters/react_to_ui_component.ts +++ b/src/plugins/kibana_react/public/adapters/react_to_ui_component.ts @@ -19,7 +19,7 @@ import { ComponentType, createElement as h } from 'react'; import { render as renderReact, unmountComponentAtNode } from 'react-dom'; -import { UiComponent, UiComponentInstance } from '../../../kibana_utils/common'; +import { UiComponent, UiComponentInstance } from '../../../kibana_utils/public'; /** * Transform a React component into a `UiComponent`. diff --git a/src/plugins/kibana_react/public/adapters/ui_to_react_component.test.tsx b/src/plugins/kibana_react/public/adapters/ui_to_react_component.test.tsx index 939d372b9997f..aefbd66e50fcf 100644 --- a/src/plugins/kibana_react/public/adapters/ui_to_react_component.test.tsx +++ b/src/plugins/kibana_react/public/adapters/ui_to_react_component.test.tsx @@ -19,7 +19,7 @@ import * as React from 'react'; import * as ReactDOM from 'react-dom'; -import { UiComponent } from '../../../kibana_utils/common'; +import { UiComponent } from '../../../kibana_utils/public'; import { uiToReactComponent } from './ui_to_react_component'; import { reactToUiComponent } from './react_to_ui_component'; diff --git a/src/plugins/kibana_react/public/adapters/ui_to_react_component.ts b/src/plugins/kibana_react/public/adapters/ui_to_react_component.ts index 9b34880cf4fe3..ee99ea3672672 100644 --- a/src/plugins/kibana_react/public/adapters/ui_to_react_component.ts +++ b/src/plugins/kibana_react/public/adapters/ui_to_react_component.ts @@ -18,7 +18,7 @@ */ import { FC, createElement as h, useRef, useLayoutEffect, useMemo } from 'react'; -import { UiComponent, UiComponentInstance } from '../../../kibana_utils/common'; +import { UiComponent, UiComponentInstance } from '../../../kibana_utils/public'; /** * Transforms `UiComponent` into a React component. diff --git a/src/plugins/kibana_react/public/index.ts b/src/plugins/kibana_react/public/index.ts index e1689e38dbfe0..9ad9f14ac5659 100644 --- a/src/plugins/kibana_react/public/index.ts +++ b/src/plugins/kibana_react/public/index.ts @@ -31,3 +31,11 @@ export { Markdown, MarkdownSimple } from './markdown'; export { reactToUiComponent, uiToReactComponent } from './adapters'; export { useUrlTracker } from './use_url_tracker'; export { toMountPoint } from './util'; + +/** dummy plugin, we just want kibanaReact to have its own bundle */ +export function plugin() { + return new (class KibanaReactPlugin { + setup() {} + start() {} + })(); +} diff --git a/src/plugins/kibana_utils/kibana.json b/src/plugins/kibana_utils/kibana.json new file mode 100644 index 0000000000000..6fa39d82d1021 --- /dev/null +++ b/src/plugins/kibana_utils/kibana.json @@ -0,0 +1,5 @@ +{ + "id": "kibanaUtils", + "version": "kibana", + "ui": true +} diff --git a/src/plugins/kibana_utils/public/index.ts b/src/plugins/kibana_utils/public/index.ts index 1876e688c989a..2f139050e994a 100644 --- a/src/plugins/kibana_utils/public/index.ts +++ b/src/plugins/kibana_utils/public/index.ts @@ -19,7 +19,6 @@ export { calculateObjectHash, - createGetterSetter, defer, Defer, Get, @@ -31,6 +30,8 @@ export { UiComponent, UiComponentInstance, url, + createGetterSetter, + defaultFeedbackMessage, } from '../common'; export * from './core'; export * from './errors'; @@ -75,3 +76,11 @@ export { } from './state_sync'; export { removeQueryParam, redirectWhenMissing, ensureDefaultIndexPattern } from './history'; export { applyDiff } from './state_management/utils/diff_object'; + +/** dummy plugin, we just want kibanaUtils to have its own bundle */ +export function plugin() { + return new (class KibanaUtilsPlugin { + setup() {} + start() {} + })(); +} diff --git a/src/plugins/ui_actions/public/actions/action.ts b/src/plugins/ui_actions/public/actions/action.ts index 2b2fc004a84c6..f532c2c8aa219 100644 --- a/src/plugins/ui_actions/public/actions/action.ts +++ b/src/plugins/ui_actions/public/actions/action.ts @@ -17,7 +17,7 @@ * under the License. */ -import { UiComponent } from 'src/plugins/kibana_utils/common'; +import { UiComponent } from 'src/plugins/kibana_utils/public'; import { ActionType, ActionContextMapping } from '../types'; export type ActionByType = Action; diff --git a/src/plugins/ui_actions/public/actions/action_definition.ts b/src/plugins/ui_actions/public/actions/action_definition.ts index c590cf8f34ee0..3eaa13572a826 100644 --- a/src/plugins/ui_actions/public/actions/action_definition.ts +++ b/src/plugins/ui_actions/public/actions/action_definition.ts @@ -17,7 +17,7 @@ * under the License. */ -import { UiComponent } from 'src/plugins/kibana_utils/common'; +import { UiComponent } from 'src/plugins/kibana_utils/public'; import { ActionType, ActionContextMapping } from '../types'; export interface ActionDefinition { From f84773faed53cf0c3683406d5eaccb5f51975cda Mon Sep 17 00:00:00 2001 From: Josh Dover Date: Wed, 8 Apr 2020 13:16:32 -0600 Subject: [PATCH 29/40] Add basic StatusService (#60335) --- .../kibana-plugin-core-server.coresetup.md | 1 + ...ana-plugin-core-server.coresetup.status.md | 13 + ...in-core-server.corestatus.elasticsearch.md | 11 + .../kibana-plugin-core-server.corestatus.md | 21 ++ ...gin-core-server.corestatus.savedobjects.md | 11 + ...asticsearchstatusmeta.incompatiblenodes.md | 11 + ...gin-core-server.elasticsearchstatusmeta.md | 20 ++ ...er.elasticsearchstatusmeta.warningnodes.md | 11 + .../core/server/kibana-plugin-core-server.md | 8 + ...sversioncompatibility.incompatiblenodes.md | 11 + ....nodesversioncompatibility.iscompatible.md | 11 + ...nodesversioncompatibility.kibanaversion.md | 11 + ...n-core-server.nodesversioncompatibility.md | 22 ++ ...erver.nodesversioncompatibility.message.md | 11 + ....nodesversioncompatibility.warningnodes.md | 11 + ...lugin-core-server.savedobjectstatusmeta.md | 20 ++ ...r.savedobjectstatusmeta.migratedindices.md | 15 ++ ...plugin-core-server.servicestatus.detail.md | 13 + ...e-server.servicestatus.documentationurl.md | 13 + ...-plugin-core-server.servicestatus.level.md | 13 + ...kibana-plugin-core-server.servicestatus.md | 24 ++ ...a-plugin-core-server.servicestatus.meta.md | 13 + ...lugin-core-server.servicestatus.summary.md | 13 + ...a-plugin-core-server.servicestatuslevel.md | 13 + ...-plugin-core-server.servicestatuslevels.md | 37 +++ ...in-core-server.statusservicesetup.core_.md | 13 + ...a-plugin-core-server.statusservicesetup.md | 20 ++ .../kibana-plugin-plugins-data-server.md | 1 - .../elasticsearch_service.mock.ts | 6 + .../elasticsearch/elasticsearch_service.ts | 2 + src/core/server/elasticsearch/index.ts | 1 + src/core/server/elasticsearch/status.test.ts | 222 +++++++++++++++++ src/core/server/elasticsearch/status.ts | 78 ++++++ src/core/server/elasticsearch/types.ts | 8 + .../version_check/ensure_es_version.ts | 2 +- src/core/server/index.ts | 18 +- src/core/server/internal_types.ts | 6 +- src/core/server/legacy/legacy_service.test.ts | 2 + src/core/server/legacy/legacy_service.ts | 3 + src/core/server/mocks.ts | 9 +- src/core/server/plugins/plugin_context.ts | 3 + src/core/server/saved_objects/index.ts | 6 +- .../saved_objects/migrations/core/index.ts | 2 +- .../migrations/core/migration_coordinator.ts | 2 + .../server/saved_objects/migrations/index.ts | 1 + .../saved_objects/migrations/kibana/index.ts | 2 +- .../migrations/kibana/kibana_migrator.mock.ts | 17 +- .../migrations/kibana/kibana_migrator.test.ts | 28 +++ .../migrations/kibana/kibana_migrator.ts | 29 ++- .../saved_objects_service.mock.ts | 7 + .../saved_objects/saved_objects_service.ts | 16 +- src/core/server/saved_objects/status.test.ts | 134 ++++++++++ src/core/server/saved_objects/status.ts | 84 +++++++ src/core/server/saved_objects/types.ts | 13 + src/core/server/server.api.md | 83 +++++++ src/core/server/server.test.mocks.ts | 6 + src/core/server/server.test.ts | 7 + src/core/server/server.ts | 18 +- .../server/status/get_summary_status.test.ts | 180 ++++++++++++++ src/core/server/status/get_summary_status.ts | 84 +++++++ src/core/server/status/index.ts | 21 ++ src/core/server/status/status_service.mock.ts | 71 ++++++ src/core/server/status/status_service.test.ts | 229 ++++++++++++++++++ src/core/server/status/status_service.ts | 78 ++++++ src/core/server/status/test_utils.ts | 25 ++ src/core/server/status/types.ts | 134 ++++++++++ src/core/server/test_utils.ts | 1 + 67 files changed, 2006 insertions(+), 24 deletions(-) create mode 100644 docs/development/core/server/kibana-plugin-core-server.coresetup.status.md create mode 100644 docs/development/core/server/kibana-plugin-core-server.corestatus.elasticsearch.md create mode 100644 docs/development/core/server/kibana-plugin-core-server.corestatus.md create mode 100644 docs/development/core/server/kibana-plugin-core-server.corestatus.savedobjects.md create mode 100644 docs/development/core/server/kibana-plugin-core-server.elasticsearchstatusmeta.incompatiblenodes.md create mode 100644 docs/development/core/server/kibana-plugin-core-server.elasticsearchstatusmeta.md create mode 100644 docs/development/core/server/kibana-plugin-core-server.elasticsearchstatusmeta.warningnodes.md create mode 100644 docs/development/core/server/kibana-plugin-core-server.nodesversioncompatibility.incompatiblenodes.md create mode 100644 docs/development/core/server/kibana-plugin-core-server.nodesversioncompatibility.iscompatible.md create mode 100644 docs/development/core/server/kibana-plugin-core-server.nodesversioncompatibility.kibanaversion.md create mode 100644 docs/development/core/server/kibana-plugin-core-server.nodesversioncompatibility.md create mode 100644 docs/development/core/server/kibana-plugin-core-server.nodesversioncompatibility.message.md create mode 100644 docs/development/core/server/kibana-plugin-core-server.nodesversioncompatibility.warningnodes.md create mode 100644 docs/development/core/server/kibana-plugin-core-server.savedobjectstatusmeta.md create mode 100644 docs/development/core/server/kibana-plugin-core-server.savedobjectstatusmeta.migratedindices.md create mode 100644 docs/development/core/server/kibana-plugin-core-server.servicestatus.detail.md create mode 100644 docs/development/core/server/kibana-plugin-core-server.servicestatus.documentationurl.md create mode 100644 docs/development/core/server/kibana-plugin-core-server.servicestatus.level.md create mode 100644 docs/development/core/server/kibana-plugin-core-server.servicestatus.md create mode 100644 docs/development/core/server/kibana-plugin-core-server.servicestatus.meta.md create mode 100644 docs/development/core/server/kibana-plugin-core-server.servicestatus.summary.md create mode 100644 docs/development/core/server/kibana-plugin-core-server.servicestatuslevel.md create mode 100644 docs/development/core/server/kibana-plugin-core-server.servicestatuslevels.md create mode 100644 docs/development/core/server/kibana-plugin-core-server.statusservicesetup.core_.md create mode 100644 docs/development/core/server/kibana-plugin-core-server.statusservicesetup.md create mode 100644 src/core/server/elasticsearch/status.test.ts create mode 100644 src/core/server/elasticsearch/status.ts create mode 100644 src/core/server/saved_objects/status.test.ts create mode 100644 src/core/server/saved_objects/status.ts create mode 100644 src/core/server/status/get_summary_status.test.ts create mode 100644 src/core/server/status/get_summary_status.ts create mode 100644 src/core/server/status/index.ts create mode 100644 src/core/server/status/status_service.mock.ts create mode 100644 src/core/server/status/status_service.test.ts create mode 100644 src/core/server/status/status_service.ts create mode 100644 src/core/server/status/test_utils.ts create mode 100644 src/core/server/status/types.ts diff --git a/docs/development/core/server/kibana-plugin-core-server.coresetup.md b/docs/development/core/server/kibana-plugin-core-server.coresetup.md index 29fdc37a81176..c10b460da8b4f 100644 --- a/docs/development/core/server/kibana-plugin-core-server.coresetup.md +++ b/docs/development/core/server/kibana-plugin-core-server.coresetup.md @@ -23,6 +23,7 @@ export interface CoreSetupHttpServiceSetup | [HttpServiceSetup](./kibana-plugin-core-server.httpservicesetup.md) | | [metrics](./kibana-plugin-core-server.coresetup.metrics.md) | MetricsServiceSetup | [MetricsServiceSetup](./kibana-plugin-core-server.metricsservicesetup.md) | | [savedObjects](./kibana-plugin-core-server.coresetup.savedobjects.md) | SavedObjectsServiceSetup | [SavedObjectsServiceSetup](./kibana-plugin-core-server.savedobjectsservicesetup.md) | +| [status](./kibana-plugin-core-server.coresetup.status.md) | StatusServiceSetup | [StatusServiceSetup](./kibana-plugin-core-server.statusservicesetup.md) | | [uiSettings](./kibana-plugin-core-server.coresetup.uisettings.md) | UiSettingsServiceSetup | [UiSettingsServiceSetup](./kibana-plugin-core-server.uisettingsservicesetup.md) | | [uuid](./kibana-plugin-core-server.coresetup.uuid.md) | UuidServiceSetup | [UuidServiceSetup](./kibana-plugin-core-server.uuidservicesetup.md) | diff --git a/docs/development/core/server/kibana-plugin-core-server.coresetup.status.md b/docs/development/core/server/kibana-plugin-core-server.coresetup.status.md new file mode 100644 index 0000000000000..f5ea627a9f008 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.coresetup.status.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [CoreSetup](./kibana-plugin-core-server.coresetup.md) > [status](./kibana-plugin-core-server.coresetup.status.md) + +## CoreSetup.status property + +[StatusServiceSetup](./kibana-plugin-core-server.statusservicesetup.md) + +Signature: + +```typescript +status: StatusServiceSetup; +``` diff --git a/docs/development/core/server/kibana-plugin-core-server.corestatus.elasticsearch.md b/docs/development/core/server/kibana-plugin-core-server.corestatus.elasticsearch.md new file mode 100644 index 0000000000000..b41e7020c38e9 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.corestatus.elasticsearch.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [CoreStatus](./kibana-plugin-core-server.corestatus.md) > [elasticsearch](./kibana-plugin-core-server.corestatus.elasticsearch.md) + +## CoreStatus.elasticsearch property + +Signature: + +```typescript +elasticsearch: ServiceStatus; +``` diff --git a/docs/development/core/server/kibana-plugin-core-server.corestatus.md b/docs/development/core/server/kibana-plugin-core-server.corestatus.md new file mode 100644 index 0000000000000..3fde86a18c58b --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.corestatus.md @@ -0,0 +1,21 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [CoreStatus](./kibana-plugin-core-server.corestatus.md) + +## CoreStatus interface + +Status of core services. + +Signature: + +```typescript +export interface CoreStatus +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [elasticsearch](./kibana-plugin-core-server.corestatus.elasticsearch.md) | ServiceStatus | | +| [savedObjects](./kibana-plugin-core-server.corestatus.savedobjects.md) | ServiceStatus | | + diff --git a/docs/development/core/server/kibana-plugin-core-server.corestatus.savedobjects.md b/docs/development/core/server/kibana-plugin-core-server.corestatus.savedobjects.md new file mode 100644 index 0000000000000..d554c6f70d720 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.corestatus.savedobjects.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [CoreStatus](./kibana-plugin-core-server.corestatus.md) > [savedObjects](./kibana-plugin-core-server.corestatus.savedobjects.md) + +## CoreStatus.savedObjects property + +Signature: + +```typescript +savedObjects: ServiceStatus; +``` diff --git a/docs/development/core/server/kibana-plugin-core-server.elasticsearchstatusmeta.incompatiblenodes.md b/docs/development/core/server/kibana-plugin-core-server.elasticsearchstatusmeta.incompatiblenodes.md new file mode 100644 index 0000000000000..f8a45fe9a5a9c --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.elasticsearchstatusmeta.incompatiblenodes.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [ElasticsearchStatusMeta](./kibana-plugin-core-server.elasticsearchstatusmeta.md) > [incompatibleNodes](./kibana-plugin-core-server.elasticsearchstatusmeta.incompatiblenodes.md) + +## ElasticsearchStatusMeta.incompatibleNodes property + +Signature: + +```typescript +incompatibleNodes: NodesVersionCompatibility['incompatibleNodes']; +``` diff --git a/docs/development/core/server/kibana-plugin-core-server.elasticsearchstatusmeta.md b/docs/development/core/server/kibana-plugin-core-server.elasticsearchstatusmeta.md new file mode 100644 index 0000000000000..2398410fa4b84 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.elasticsearchstatusmeta.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [ElasticsearchStatusMeta](./kibana-plugin-core-server.elasticsearchstatusmeta.md) + +## ElasticsearchStatusMeta interface + + +Signature: + +```typescript +export interface ElasticsearchStatusMeta +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [incompatibleNodes](./kibana-plugin-core-server.elasticsearchstatusmeta.incompatiblenodes.md) | NodesVersionCompatibility['incompatibleNodes'] | | +| [warningNodes](./kibana-plugin-core-server.elasticsearchstatusmeta.warningnodes.md) | NodesVersionCompatibility['warningNodes'] | | + diff --git a/docs/development/core/server/kibana-plugin-core-server.elasticsearchstatusmeta.warningnodes.md b/docs/development/core/server/kibana-plugin-core-server.elasticsearchstatusmeta.warningnodes.md new file mode 100644 index 0000000000000..7374ccd9e7fa8 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.elasticsearchstatusmeta.warningnodes.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [ElasticsearchStatusMeta](./kibana-plugin-core-server.elasticsearchstatusmeta.md) > [warningNodes](./kibana-plugin-core-server.elasticsearchstatusmeta.warningnodes.md) + +## ElasticsearchStatusMeta.warningNodes property + +Signature: + +```typescript +warningNodes: NodesVersionCompatibility['warningNodes']; +``` diff --git a/docs/development/core/server/kibana-plugin-core-server.md b/docs/development/core/server/kibana-plugin-core-server.md index 793684c1b3796..accab9bf0cb36 100644 --- a/docs/development/core/server/kibana-plugin-core-server.md +++ b/docs/development/core/server/kibana-plugin-core-server.md @@ -66,6 +66,7 @@ The plugin integrates with the core system via lifecycle events: `setup` | [ContextSetup](./kibana-plugin-core-server.contextsetup.md) | An object that handles registration of context providers and configuring handlers with context. | | [CoreSetup](./kibana-plugin-core-server.coresetup.md) | Context passed to the plugins setup method. | | [CoreStart](./kibana-plugin-core-server.corestart.md) | Context passed to the plugins start method. | +| [CoreStatus](./kibana-plugin-core-server.corestatus.md) | Status of core services. | | [CustomHttpResponseOptions](./kibana-plugin-core-server.customhttpresponseoptions.md) | HTTP response parameters for a response with adjustable status code. | | [DeprecationAPIClientParams](./kibana-plugin-core-server.deprecationapiclientparams.md) | | | [DeprecationAPIResponse](./kibana-plugin-core-server.deprecationapiresponse.md) | | @@ -75,6 +76,7 @@ The plugin integrates with the core system via lifecycle events: `setup` | [ElasticsearchError](./kibana-plugin-core-server.elasticsearcherror.md) | | | [ElasticsearchServiceSetup](./kibana-plugin-core-server.elasticsearchservicesetup.md) | | | [ElasticsearchServiceStart](./kibana-plugin-core-server.elasticsearchservicestart.md) | | +| [ElasticsearchStatusMeta](./kibana-plugin-core-server.elasticsearchstatusmeta.md) | | | [EnvironmentMode](./kibana-plugin-core-server.environmentmode.md) | | | [ErrorHttpResponseOptions](./kibana-plugin-core-server.errorhttpresponseoptions.md) | HTTP response parameters | | [FakeRequest](./kibana-plugin-core-server.fakerequest.md) | Fake request object created manually by Kibana plugins. | @@ -101,6 +103,7 @@ The plugin integrates with the core system via lifecycle events: `setup` | [LoggerFactory](./kibana-plugin-core-server.loggerfactory.md) | The single purpose of LoggerFactory interface is to define a way to retrieve a context-based logger instance. | | [LogMeta](./kibana-plugin-core-server.logmeta.md) | Contextual metadata | | [MetricsServiceSetup](./kibana-plugin-core-server.metricsservicesetup.md) | APIs to retrieves metrics gathered and exposed by the core platform. | +| [NodesVersionCompatibility](./kibana-plugin-core-server.nodesversioncompatibility.md) | | | [OnPostAuthToolkit](./kibana-plugin-core-server.onpostauthtoolkit.md) | A tool set defining an outcome of OnPostAuth interceptor for incoming request. | | [OnPreAuthToolkit](./kibana-plugin-core-server.onpreauthtoolkit.md) | A tool set defining an outcome of OnPreAuth interceptor for incoming request. | | [OnPreResponseExtensions](./kibana-plugin-core-server.onpreresponseextensions.md) | Additional data to extend a response. | @@ -162,15 +165,18 @@ The plugin integrates with the core system via lifecycle events: `setup` | [SavedObjectsResolveImportErrorsOptions](./kibana-plugin-core-server.savedobjectsresolveimporterrorsoptions.md) | Options to control the "resolve import" operation. | | [SavedObjectsServiceSetup](./kibana-plugin-core-server.savedobjectsservicesetup.md) | Saved Objects is Kibana's data persistence mechanism allowing plugins to use Elasticsearch for storing and querying state. The SavedObjectsServiceSetup API exposes methods for registering Saved Object types, creating and registering Saved Object client wrappers and factories. | | [SavedObjectsServiceStart](./kibana-plugin-core-server.savedobjectsservicestart.md) | Saved Objects is Kibana's data persisentence mechanism allowing plugins to use Elasticsearch for storing and querying state. The SavedObjectsServiceStart API provides a scoped Saved Objects client for interacting with Saved Objects. | +| [SavedObjectStatusMeta](./kibana-plugin-core-server.savedobjectstatusmeta.md) | Meta information about the SavedObjectService's status. Available to plugins via [CoreSetup.status](./kibana-plugin-core-server.coresetup.status.md). | | [SavedObjectsType](./kibana-plugin-core-server.savedobjectstype.md) | | | [SavedObjectsTypeManagementDefinition](./kibana-plugin-core-server.savedobjectstypemanagementdefinition.md) | Configuration options for the [type](./kibana-plugin-core-server.savedobjectstype.md)'s management section. | | [SavedObjectsTypeMappingDefinition](./kibana-plugin-core-server.savedobjectstypemappingdefinition.md) | Describe a saved object type mapping. | | [SavedObjectsUpdateOptions](./kibana-plugin-core-server.savedobjectsupdateoptions.md) | | | [SavedObjectsUpdateResponse](./kibana-plugin-core-server.savedobjectsupdateresponse.md) | | +| [ServiceStatus](./kibana-plugin-core-server.servicestatus.md) | The current status of a service at a point in time. | | [SessionCookieValidationResult](./kibana-plugin-core-server.sessioncookievalidationresult.md) | Return type from a function to validate cookie contents. | | [SessionStorage](./kibana-plugin-core-server.sessionstorage.md) | Provides an interface to store and retrieve data across requests. | | [SessionStorageCookieOptions](./kibana-plugin-core-server.sessionstoragecookieoptions.md) | Configuration used to create HTTP session storage based on top of cookie mechanism. | | [SessionStorageFactory](./kibana-plugin-core-server.sessionstoragefactory.md) | SessionStorage factory to bind one to an incoming request | +| [StatusServiceSetup](./kibana-plugin-core-server.statusservicesetup.md) | API for accessing status of Core and this plugin's dependencies as well as for customizing this plugin's status. | | [StringValidationRegex](./kibana-plugin-core-server.stringvalidationregex.md) | StringValidation with regex object | | [StringValidationRegexString](./kibana-plugin-core-server.stringvalidationregexstring.md) | StringValidation as regex string | | [UiSettingsParams](./kibana-plugin-core-server.uisettingsparams.md) | UiSettings parameters defined by the plugins. | @@ -184,6 +190,7 @@ The plugin integrates with the core system via lifecycle events: `setup` | Variable | Description | | --- | --- | | [kibanaResponseFactory](./kibana-plugin-core-server.kibanaresponsefactory.md) | Set of helpers used to create KibanaResponse to form HTTP response on an incoming request. Should be returned as a result of [RequestHandler](./kibana-plugin-core-server.requesthandler.md) execution. | +| [ServiceStatusLevels](./kibana-plugin-core-server.servicestatuslevels.md) | The current "level" of availability of a service. | | [validBodyOutput](./kibana-plugin-core-server.validbodyoutput.md) | The set of valid body.output | ## Type Aliases @@ -256,6 +263,7 @@ The plugin integrates with the core system via lifecycle events: `setup` | [SavedObjectsClientWrapperFactory](./kibana-plugin-core-server.savedobjectsclientwrapperfactory.md) | Describes the factory used to create instances of Saved Objects Client Wrappers. | | [SavedObjectsFieldMapping](./kibana-plugin-core-server.savedobjectsfieldmapping.md) | Describe a [saved object type mapping](./kibana-plugin-core-server.savedobjectstypemappingdefinition.md) field.Please refer to [elasticsearch documentation](https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-types.html) For the mapping documentation | | [ScopeableRequest](./kibana-plugin-core-server.scopeablerequest.md) | A user credentials container. It accommodates the necessary auth credentials to impersonate the current user.See [KibanaRequest](./kibana-plugin-core-server.kibanarequest.md). | +| [ServiceStatusLevel](./kibana-plugin-core-server.servicestatuslevel.md) | A convenience type that represents the union of each value in [ServiceStatusLevels](./kibana-plugin-core-server.servicestatuslevels.md). | | [SharedGlobalConfig](./kibana-plugin-core-server.sharedglobalconfig.md) | | | [StartServicesAccessor](./kibana-plugin-core-server.startservicesaccessor.md) | Allows plugins to get access to APIs available in start inside async handlers. Promise will not resolve until Core and plugin dependencies have completed start. This should only be used inside handlers registered during setup that will only be executed after start lifecycle. | | [StringValidation](./kibana-plugin-core-server.stringvalidation.md) | Allows regex objects or a regex string | diff --git a/docs/development/core/server/kibana-plugin-core-server.nodesversioncompatibility.incompatiblenodes.md b/docs/development/core/server/kibana-plugin-core-server.nodesversioncompatibility.incompatiblenodes.md new file mode 100644 index 0000000000000..8e7298d28801c --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.nodesversioncompatibility.incompatiblenodes.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [NodesVersionCompatibility](./kibana-plugin-core-server.nodesversioncompatibility.md) > [incompatibleNodes](./kibana-plugin-core-server.nodesversioncompatibility.incompatiblenodes.md) + +## NodesVersionCompatibility.incompatibleNodes property + +Signature: + +```typescript +incompatibleNodes: NodeInfo[]; +``` diff --git a/docs/development/core/server/kibana-plugin-core-server.nodesversioncompatibility.iscompatible.md b/docs/development/core/server/kibana-plugin-core-server.nodesversioncompatibility.iscompatible.md new file mode 100644 index 0000000000000..82a4800a3b4b6 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.nodesversioncompatibility.iscompatible.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [NodesVersionCompatibility](./kibana-plugin-core-server.nodesversioncompatibility.md) > [isCompatible](./kibana-plugin-core-server.nodesversioncompatibility.iscompatible.md) + +## NodesVersionCompatibility.isCompatible property + +Signature: + +```typescript +isCompatible: boolean; +``` diff --git a/docs/development/core/server/kibana-plugin-core-server.nodesversioncompatibility.kibanaversion.md b/docs/development/core/server/kibana-plugin-core-server.nodesversioncompatibility.kibanaversion.md new file mode 100644 index 0000000000000..347f2d3474b11 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.nodesversioncompatibility.kibanaversion.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [NodesVersionCompatibility](./kibana-plugin-core-server.nodesversioncompatibility.md) > [kibanaVersion](./kibana-plugin-core-server.nodesversioncompatibility.kibanaversion.md) + +## NodesVersionCompatibility.kibanaVersion property + +Signature: + +```typescript +kibanaVersion: string; +``` diff --git a/docs/development/core/server/kibana-plugin-core-server.nodesversioncompatibility.md b/docs/development/core/server/kibana-plugin-core-server.nodesversioncompatibility.md new file mode 100644 index 0000000000000..6fcfacc3bc908 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.nodesversioncompatibility.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [NodesVersionCompatibility](./kibana-plugin-core-server.nodesversioncompatibility.md) + +## NodesVersionCompatibility interface + +Signature: + +```typescript +export interface NodesVersionCompatibility +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [incompatibleNodes](./kibana-plugin-core-server.nodesversioncompatibility.incompatiblenodes.md) | NodeInfo[] | | +| [isCompatible](./kibana-plugin-core-server.nodesversioncompatibility.iscompatible.md) | boolean | | +| [kibanaVersion](./kibana-plugin-core-server.nodesversioncompatibility.kibanaversion.md) | string | | +| [message](./kibana-plugin-core-server.nodesversioncompatibility.message.md) | string | | +| [warningNodes](./kibana-plugin-core-server.nodesversioncompatibility.warningnodes.md) | NodeInfo[] | | + diff --git a/docs/development/core/server/kibana-plugin-core-server.nodesversioncompatibility.message.md b/docs/development/core/server/kibana-plugin-core-server.nodesversioncompatibility.message.md new file mode 100644 index 0000000000000..415a7825ee2bf --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.nodesversioncompatibility.message.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [NodesVersionCompatibility](./kibana-plugin-core-server.nodesversioncompatibility.md) > [message](./kibana-plugin-core-server.nodesversioncompatibility.message.md) + +## NodesVersionCompatibility.message property + +Signature: + +```typescript +message?: string; +``` diff --git a/docs/development/core/server/kibana-plugin-core-server.nodesversioncompatibility.warningnodes.md b/docs/development/core/server/kibana-plugin-core-server.nodesversioncompatibility.warningnodes.md new file mode 100644 index 0000000000000..6c017e9fc800c --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.nodesversioncompatibility.warningnodes.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [NodesVersionCompatibility](./kibana-plugin-core-server.nodesversioncompatibility.md) > [warningNodes](./kibana-plugin-core-server.nodesversioncompatibility.warningnodes.md) + +## NodesVersionCompatibility.warningNodes property + +Signature: + +```typescript +warningNodes: NodeInfo[]; +``` diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectstatusmeta.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectstatusmeta.md new file mode 100644 index 0000000000000..3a0b23d18632f --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectstatusmeta.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [SavedObjectStatusMeta](./kibana-plugin-core-server.savedobjectstatusmeta.md) + +## SavedObjectStatusMeta interface + +Meta information about the SavedObjectService's status. Available to plugins via [CoreSetup.status](./kibana-plugin-core-server.coresetup.status.md). + +Signature: + +```typescript +export interface SavedObjectStatusMeta +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [migratedIndices](./kibana-plugin-core-server.savedobjectstatusmeta.migratedindices.md) | {
[status: string]: number;
skipped: number;
migrated: number;
} | | + diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectstatusmeta.migratedindices.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectstatusmeta.migratedindices.md new file mode 100644 index 0000000000000..6a29623b2f122 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectstatusmeta.migratedindices.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [SavedObjectStatusMeta](./kibana-plugin-core-server.savedobjectstatusmeta.md) > [migratedIndices](./kibana-plugin-core-server.savedobjectstatusmeta.migratedindices.md) + +## SavedObjectStatusMeta.migratedIndices property + +Signature: + +```typescript +migratedIndices: { + [status: string]: number; + skipped: number; + migrated: number; + }; +``` diff --git a/docs/development/core/server/kibana-plugin-core-server.servicestatus.detail.md b/docs/development/core/server/kibana-plugin-core-server.servicestatus.detail.md new file mode 100644 index 0000000000000..fa369aa0bdfbb --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.servicestatus.detail.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [ServiceStatus](./kibana-plugin-core-server.servicestatus.md) > [detail](./kibana-plugin-core-server.servicestatus.detail.md) + +## ServiceStatus.detail property + +A more detailed description of the service status. + +Signature: + +```typescript +detail?: string; +``` diff --git a/docs/development/core/server/kibana-plugin-core-server.servicestatus.documentationurl.md b/docs/development/core/server/kibana-plugin-core-server.servicestatus.documentationurl.md new file mode 100644 index 0000000000000..5ef8c1251a602 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.servicestatus.documentationurl.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [ServiceStatus](./kibana-plugin-core-server.servicestatus.md) > [documentationUrl](./kibana-plugin-core-server.servicestatus.documentationurl.md) + +## ServiceStatus.documentationUrl property + +A URL to open in a new tab about how to resolve or troubleshoot the problem. + +Signature: + +```typescript +documentationUrl?: string; +``` diff --git a/docs/development/core/server/kibana-plugin-core-server.servicestatus.level.md b/docs/development/core/server/kibana-plugin-core-server.servicestatus.level.md new file mode 100644 index 0000000000000..551c10c9bff82 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.servicestatus.level.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [ServiceStatus](./kibana-plugin-core-server.servicestatus.md) > [level](./kibana-plugin-core-server.servicestatus.level.md) + +## ServiceStatus.level property + +The current availability level of the service. + +Signature: + +```typescript +level: ServiceStatusLevel; +``` diff --git a/docs/development/core/server/kibana-plugin-core-server.servicestatus.md b/docs/development/core/server/kibana-plugin-core-server.servicestatus.md new file mode 100644 index 0000000000000..d35fc951c57ff --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.servicestatus.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [ServiceStatus](./kibana-plugin-core-server.servicestatus.md) + +## ServiceStatus interface + +The current status of a service at a point in time. + +Signature: + +```typescript +export interface ServiceStatus | unknown = unknown> +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [detail](./kibana-plugin-core-server.servicestatus.detail.md) | string | A more detailed description of the service status. | +| [documentationUrl](./kibana-plugin-core-server.servicestatus.documentationurl.md) | string | A URL to open in a new tab about how to resolve or troubleshoot the problem. | +| [level](./kibana-plugin-core-server.servicestatus.level.md) | ServiceStatusLevel | The current availability level of the service. | +| [meta](./kibana-plugin-core-server.servicestatus.meta.md) | Meta | Any JSON-serializable data to be included in the HTTP API response. Useful for providing more fine-grained, machine-readable information about the service status. May include status information for underlying features. | +| [summary](./kibana-plugin-core-server.servicestatus.summary.md) | string | A high-level summary of the service status. | + diff --git a/docs/development/core/server/kibana-plugin-core-server.servicestatus.meta.md b/docs/development/core/server/kibana-plugin-core-server.servicestatus.meta.md new file mode 100644 index 0000000000000..a48994daa5a4e --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.servicestatus.meta.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [ServiceStatus](./kibana-plugin-core-server.servicestatus.md) > [meta](./kibana-plugin-core-server.servicestatus.meta.md) + +## ServiceStatus.meta property + +Any JSON-serializable data to be included in the HTTP API response. Useful for providing more fine-grained, machine-readable information about the service status. May include status information for underlying features. + +Signature: + +```typescript +meta?: Meta; +``` diff --git a/docs/development/core/server/kibana-plugin-core-server.servicestatus.summary.md b/docs/development/core/server/kibana-plugin-core-server.servicestatus.summary.md new file mode 100644 index 0000000000000..db90afd6f74a6 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.servicestatus.summary.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [ServiceStatus](./kibana-plugin-core-server.servicestatus.md) > [summary](./kibana-plugin-core-server.servicestatus.summary.md) + +## ServiceStatus.summary property + +A high-level summary of the service status. + +Signature: + +```typescript +summary: string; +``` diff --git a/docs/development/core/server/kibana-plugin-core-server.servicestatuslevel.md b/docs/development/core/server/kibana-plugin-core-server.servicestatuslevel.md new file mode 100644 index 0000000000000..5f995ff5e13e3 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.servicestatuslevel.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [ServiceStatusLevel](./kibana-plugin-core-server.servicestatuslevel.md) + +## ServiceStatusLevel type + +A convenience type that represents the union of each value in [ServiceStatusLevels](./kibana-plugin-core-server.servicestatuslevels.md). + +Signature: + +```typescript +export declare type ServiceStatusLevel = typeof ServiceStatusLevels[keyof typeof ServiceStatusLevels]; +``` diff --git a/docs/development/core/server/kibana-plugin-core-server.servicestatuslevels.md b/docs/development/core/server/kibana-plugin-core-server.servicestatuslevels.md new file mode 100644 index 0000000000000..a66cec78c736b --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.servicestatuslevels.md @@ -0,0 +1,37 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [ServiceStatusLevels](./kibana-plugin-core-server.servicestatuslevels.md) + +## ServiceStatusLevels variable + +The current "level" of availability of a service. + +Signature: + +```typescript +ServiceStatusLevels: Readonly<{ + available: Readonly<{ + toString: () => "available"; + valueOf: () => 0; + }>; + degraded: Readonly<{ + toString: () => "degraded"; + valueOf: () => 1; + }>; + unavailable: Readonly<{ + toString: () => "unavailable"; + valueOf: () => 2; + }>; + critical: Readonly<{ + toString: () => "critical"; + valueOf: () => 3; + }>; +}> +``` + +## Remarks + +The values implement `valueOf` to allow for easy comparisons between status levels with <, >, etc. Higher values represent higher severities. Note that the default `Array.prototype.sort` implementation does not correctly sort these values. + +A snapshot serializer is available in `src/core/server/test_utils` to ease testing of these values with Jest. + diff --git a/docs/development/core/server/kibana-plugin-core-server.statusservicesetup.core_.md b/docs/development/core/server/kibana-plugin-core-server.statusservicesetup.core_.md new file mode 100644 index 0000000000000..6662e68b44d36 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.statusservicesetup.core_.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [StatusServiceSetup](./kibana-plugin-core-server.statusservicesetup.md) > [core$](./kibana-plugin-core-server.statusservicesetup.core_.md) + +## StatusServiceSetup.core$ property + +Current status for all Core services. + +Signature: + +```typescript +core$: Observable; +``` diff --git a/docs/development/core/server/kibana-plugin-core-server.statusservicesetup.md b/docs/development/core/server/kibana-plugin-core-server.statusservicesetup.md new file mode 100644 index 0000000000000..0551a217520ad --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.statusservicesetup.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [StatusServiceSetup](./kibana-plugin-core-server.statusservicesetup.md) + +## StatusServiceSetup interface + +API for accessing status of Core and this plugin's dependencies as well as for customizing this plugin's status. + +Signature: + +```typescript +export interface StatusServiceSetup +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [core$](./kibana-plugin-core-server.statusservicesetup.core_.md) | Observable<CoreStatus> | Current status for all Core services. | + diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.md index 259d725b3bf0d..e756eb9b72905 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.md @@ -23,7 +23,6 @@ | Function | Description | | --- | --- | | [getDefaultSearchParams(config)](./kibana-plugin-plugins-data-server.getdefaultsearchparams.md) | | -| [getTotalLoaded({ total, failed, successful })](./kibana-plugin-plugins-data-server.gettotalloaded.md) | | | [parseInterval(interval)](./kibana-plugin-plugins-data-server.parseinterval.md) | | | [plugin(initializerContext)](./kibana-plugin-plugins-data-server.plugin.md) | Static code to be shared externally | | [shouldReadFieldFromDocValues(aggregatable, esType)](./kibana-plugin-plugins-data-server.shouldreadfieldfromdocvalues.md) | | diff --git a/src/core/server/elasticsearch/elasticsearch_service.mock.ts b/src/core/server/elasticsearch/elasticsearch_service.mock.ts index 389d98a0818c8..da8846f6dddbb 100644 --- a/src/core/server/elasticsearch/elasticsearch_service.mock.ts +++ b/src/core/server/elasticsearch/elasticsearch_service.mock.ts @@ -26,8 +26,10 @@ import { InternalElasticsearchServiceSetup, ElasticsearchServiceSetup, ElasticsearchServiceStart, + ElasticsearchStatusMeta, } from './types'; import { NodesVersionCompatibility } from './version_check/ensure_es_version'; +import { ServiceStatus, ServiceStatusLevels } from '../status'; const createScopedClusterClientMock = (): jest.Mocked => ({ callAsInternalUser: jest.fn(), @@ -102,6 +104,10 @@ const createInternalSetupContractMock = () => { warningNodes: [], kibanaVersion: '8.0.0', }), + status$: new BehaviorSubject>({ + level: ServiceStatusLevels.available, + summary: 'Elasticsearch is available', + }), legacy: { config$: new BehaviorSubject({} as ElasticsearchConfig), }, diff --git a/src/core/server/elasticsearch/elasticsearch_service.ts b/src/core/server/elasticsearch/elasticsearch_service.ts index b92a6edf778ed..684f6e15caff9 100644 --- a/src/core/server/elasticsearch/elasticsearch_service.ts +++ b/src/core/server/elasticsearch/elasticsearch_service.ts @@ -40,6 +40,7 @@ import { InternalHttpServiceSetup, GetAuthHeaders } from '../http/'; import { InternalElasticsearchServiceSetup, ElasticsearchServiceStart } from './types'; import { CallAPIOptions } from './api_types'; import { pollEsNodesVersion } from './version_check/ensure_es_version'; +import { calculateStatus$ } from './status'; /** @internal */ interface CoreClusterClients { @@ -186,6 +187,7 @@ export class ElasticsearchService adminClient: this.adminClient, dataClient, createClient: this.createClient, + status$: calculateStatus$(esNodesCompatibility$), }; } diff --git a/src/core/server/elasticsearch/index.ts b/src/core/server/elasticsearch/index.ts index cfd72a6fd5e47..2e45f710c4dcf 100644 --- a/src/core/server/elasticsearch/index.ts +++ b/src/core/server/elasticsearch/index.ts @@ -31,3 +31,4 @@ export { config, configSchema, ElasticsearchConfig } from './elasticsearch_confi export { ElasticsearchError, ElasticsearchErrorHelpers } from './errors'; export * from './api_types'; export * from './types'; +export { NodesVersionCompatibility } from './version_check/ensure_es_version'; diff --git a/src/core/server/elasticsearch/status.test.ts b/src/core/server/elasticsearch/status.test.ts new file mode 100644 index 0000000000000..dd5fb04bfd1c6 --- /dev/null +++ b/src/core/server/elasticsearch/status.test.ts @@ -0,0 +1,222 @@ +/* + * 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 } from 'rxjs/operators'; +import { Subject, of } from 'rxjs'; + +import { calculateStatus$ } from './status'; +import { ServiceStatusLevels, ServiceStatus } from '../status'; +import { ServiceStatusLevelSnapshotSerializer } from '../status/test_utils'; +import { NodesVersionCompatibility } from './version_check/ensure_es_version'; + +expect.addSnapshotSerializer(ServiceStatusLevelSnapshotSerializer); + +const nodeInfo = { + version: '1.1.1', + ip: '1.1.1.1', + http: { + publish_address: 'https://1.1.1.1:9200', + }, + name: 'node1', +}; + +describe('calculateStatus', () => { + it('starts in unavailable', async () => { + expect( + await calculateStatus$(new Subject()) + .pipe(take(1)) + .toPromise() + ).toEqual({ + level: ServiceStatusLevels.unavailable, + summary: 'Waiting for Elasticsearch', + meta: { + warningNodes: [], + incompatibleNodes: [], + }, + }); + }); + + it('changes to available when isCompatible and no warningNodes', async () => { + expect( + await calculateStatus$( + of({ isCompatible: true, kibanaVersion: '1.1.1', warningNodes: [], incompatibleNodes: [] }) + ) + .pipe(take(2)) + .toPromise() + ).toEqual({ + level: ServiceStatusLevels.available, + summary: 'Elasticsearch is available', + meta: { + warningNodes: [], + incompatibleNodes: [], + }, + }); + }); + + it('changes to degraded when isCompatible and warningNodes present', async () => { + expect( + await calculateStatus$( + of({ + isCompatible: true, + kibanaVersion: '1.1.1', + warningNodes: [nodeInfo], + incompatibleNodes: [], + // this isn't the real message, just used to test that the message + // is forwarded to the status + message: 'Some nodes are a different version', + }) + ) + .pipe(take(2)) + .toPromise() + ).toEqual({ + level: ServiceStatusLevels.degraded, + summary: 'Some nodes are a different version', + meta: { + incompatibleNodes: [], + warningNodes: [nodeInfo], + }, + }); + }); + + it('changes to critical when isCompatible is false', async () => { + expect( + await calculateStatus$( + of({ + isCompatible: false, + kibanaVersion: '2.1.1', + warningNodes: [nodeInfo], + incompatibleNodes: [nodeInfo], + // this isn't the real message, just used to test that the message + // is forwarded to the status + message: 'Incompatible with Elasticsearch', + }) + ) + .pipe(take(2)) + .toPromise() + ).toEqual({ + level: ServiceStatusLevels.critical, + summary: 'Incompatible with Elasticsearch', + meta: { + incompatibleNodes: [nodeInfo], + warningNodes: [nodeInfo], + }, + }); + }); + + it('emits status updates when node compatibility changes', () => { + const nodeCompat$ = new Subject(); + + const statusUpdates: ServiceStatus[] = []; + const subscription = calculateStatus$(nodeCompat$).subscribe(status => + statusUpdates.push(status) + ); + + nodeCompat$.next({ + isCompatible: false, + kibanaVersion: '2.1.1', + incompatibleNodes: [], + warningNodes: [], + message: 'Unable to retrieve version info', + }); + nodeCompat$.next({ + isCompatible: false, + kibanaVersion: '2.1.1', + incompatibleNodes: [nodeInfo], + warningNodes: [], + message: 'Incompatible with Elasticsearch', + }); + nodeCompat$.next({ + isCompatible: true, + kibanaVersion: '1.1.1', + warningNodes: [nodeInfo], + incompatibleNodes: [], + message: 'Some nodes are incompatible', + }); + nodeCompat$.next({ + isCompatible: true, + kibanaVersion: '1.1.1', + warningNodes: [], + incompatibleNodes: [], + }); + + subscription.unsubscribe(); + expect(statusUpdates).toMatchInlineSnapshot(` + Array [ + Object { + "level": unavailable, + "meta": Object { + "incompatibleNodes": Array [], + "warningNodes": Array [], + }, + "summary": "Waiting for Elasticsearch", + }, + Object { + "level": critical, + "meta": Object { + "incompatibleNodes": Array [], + "warningNodes": Array [], + }, + "summary": "Unable to retrieve version info", + }, + Object { + "level": critical, + "meta": Object { + "incompatibleNodes": Array [ + Object { + "http": Object { + "publish_address": "https://1.1.1.1:9200", + }, + "ip": "1.1.1.1", + "name": "node1", + "version": "1.1.1", + }, + ], + "warningNodes": Array [], + }, + "summary": "Incompatible with Elasticsearch", + }, + Object { + "level": degraded, + "meta": Object { + "incompatibleNodes": Array [], + "warningNodes": Array [ + Object { + "http": Object { + "publish_address": "https://1.1.1.1:9200", + }, + "ip": "1.1.1.1", + "name": "node1", + "version": "1.1.1", + }, + ], + }, + "summary": "Some nodes are incompatible", + }, + Object { + "level": available, + "meta": Object { + "incompatibleNodes": Array [], + "warningNodes": Array [], + }, + "summary": "Elasticsearch is available", + }, + ] + `); + }); +}); diff --git a/src/core/server/elasticsearch/status.ts b/src/core/server/elasticsearch/status.ts new file mode 100644 index 0000000000000..1eaa338af1239 --- /dev/null +++ b/src/core/server/elasticsearch/status.ts @@ -0,0 +1,78 @@ +/* + * 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 { Observable, merge, of } from 'rxjs'; +import { map } from 'rxjs/operators'; + +import { ServiceStatus, ServiceStatusLevels } from '../status'; +import { ElasticsearchStatusMeta } from './types'; +import { NodesVersionCompatibility } from './version_check/ensure_es_version'; + +export const calculateStatus$ = ( + esNodesCompatibility$: Observable +): Observable> => + merge( + of({ + level: ServiceStatusLevels.unavailable, + summary: `Waiting for Elasticsearch`, + meta: { + warningNodes: [], + incompatibleNodes: [], + }, + }), + esNodesCompatibility$.pipe( + map( + ({ + isCompatible, + message, + incompatibleNodes, + warningNodes, + }): ServiceStatus => { + if (!isCompatible) { + return { + level: ServiceStatusLevels.critical, + summary: + // Message should always be present, but this is a safe fallback + message ?? + `Some Elasticsearch nodes are not compatible with this version of Kibana`, + meta: { warningNodes, incompatibleNodes }, + }; + } else if (warningNodes.length > 0) { + return { + level: ServiceStatusLevels.degraded, + summary: + // Message should always be present, but this is a safe fallback + message ?? + `Some Elasticsearch nodes are running different versions than this version of Kibana`, + meta: { warningNodes, incompatibleNodes }, + }; + } + + return { + level: ServiceStatusLevels.available, + summary: `Elasticsearch is available`, + meta: { + warningNodes: [], + incompatibleNodes: [], + }, + }; + } + ) + ) + ); diff --git a/src/core/server/elasticsearch/types.ts b/src/core/server/elasticsearch/types.ts index ef8edecfd26ec..3d38935e9fbf0 100644 --- a/src/core/server/elasticsearch/types.ts +++ b/src/core/server/elasticsearch/types.ts @@ -22,6 +22,7 @@ import { ElasticsearchConfig } from './elasticsearch_config'; import { ElasticsearchClientConfig } from './elasticsearch_client_config'; import { IClusterClient, ICustomClusterClient } from './cluster_client'; import { NodesVersionCompatibility } from './version_check/ensure_es_version'; +import { ServiceStatus } from '../status'; /** * @public @@ -128,4 +129,11 @@ export interface InternalElasticsearchServiceSetup extends ElasticsearchServiceS readonly config$: Observable; }; esNodesCompatibility$: Observable; + status$: Observable>; +} + +/** @public */ +export interface ElasticsearchStatusMeta { + warningNodes: NodesVersionCompatibility['warningNodes']; + incompatibleNodes: NodesVersionCompatibility['incompatibleNodes']; } diff --git a/src/core/server/elasticsearch/version_check/ensure_es_version.ts b/src/core/server/elasticsearch/version_check/ensure_es_version.ts index 3e760ec0efabd..7bd6331978d1d 100644 --- a/src/core/server/elasticsearch/version_check/ensure_es_version.ts +++ b/src/core/server/elasticsearch/version_check/ensure_es_version.ts @@ -142,7 +142,7 @@ export const pollEsNodesVersion = ({ kibanaVersion, ignoreVersionMismatch, esVersionCheckInterval: healthCheckInterval, -}: PollEsNodesVersionOptions): Observable => { +}: PollEsNodesVersionOptions): Observable => { log.debug('Checking Elasticsearch version'); return timer(0, healthCheckInterval).pipe( exhaustMap(() => { diff --git a/src/core/server/index.ts b/src/core/server/index.ts index 56ce16a951aa2..a298f80f96d8f 100644 --- a/src/core/server/index.ts +++ b/src/core/server/index.ts @@ -60,6 +60,7 @@ import { import { CapabilitiesSetup, CapabilitiesStart } from './capabilities'; import { UuidServiceSetup } from './uuid'; import { MetricsServiceSetup } from './metrics'; +import { StatusServiceSetup } from './status'; export { bootstrap } from './bootstrap'; export { Capabilities, CapabilitiesProvider, CapabilitiesSwitcher } from './capabilities'; @@ -95,6 +96,8 @@ export { ElasticsearchErrorHelpers, ElasticsearchServiceSetup, ElasticsearchServiceStart, + ElasticsearchStatusMeta, + NodesVersionCompatibility, APICaller, FakeRequest, ScopeableRequest, @@ -226,6 +229,7 @@ export { SavedObjectsUpdateResponse, SavedObjectsServiceStart, SavedObjectsServiceSetup, + SavedObjectStatusMeta, SavedObjectsDeleteOptions, ISavedObjectsRepository, SavedObjectsRepository, @@ -294,6 +298,14 @@ export { LegacyInternals, } from './legacy'; +export { + CoreStatus, + ServiceStatus, + ServiceStatusLevel, + ServiceStatusLevels, + StatusServiceSetup, +} from './status'; + /** * Plugin specific context passed to a route handler. * @@ -348,14 +360,16 @@ export interface CoreSetup; } diff --git a/src/core/server/internal_types.ts b/src/core/server/internal_types.ts index 825deea99bc23..ede0d3dc9fcc7 100644 --- a/src/core/server/internal_types.ts +++ b/src/core/server/internal_types.ts @@ -31,6 +31,7 @@ import { import { InternalUiSettingsServiceSetup, InternalUiSettingsServiceStart } from './ui_settings'; import { UuidServiceSetup } from './uuid'; import { InternalMetricsServiceSetup } from './metrics'; +import { InternalStatusServiceSetup } from './status'; /** @internal */ export interface InternalCoreSetup { @@ -38,10 +39,11 @@ export interface InternalCoreSetup { context: ContextSetup; http: InternalHttpServiceSetup; elasticsearch: InternalElasticsearchServiceSetup; - uiSettings: InternalUiSettingsServiceSetup; + metrics: InternalMetricsServiceSetup; savedObjects: InternalSavedObjectsServiceSetup; + status: InternalStatusServiceSetup; + uiSettings: InternalUiSettingsServiceSetup; uuid: UuidServiceSetup; - metrics: InternalMetricsServiceSetup; } /** diff --git a/src/core/server/legacy/legacy_service.test.ts b/src/core/server/legacy/legacy_service.test.ts index c6860086e7784..0cf2ebe55ea10 100644 --- a/src/core/server/legacy/legacy_service.test.ts +++ b/src/core/server/legacy/legacy_service.test.ts @@ -48,6 +48,7 @@ import { findLegacyPluginSpecs } from './plugins'; import { LegacyVars, LegacyServiceSetupDeps, LegacyServiceStartDeps } from './types'; import { LegacyService } from './legacy_service'; import { coreMock } from '../mocks'; +import { statusServiceMock } from '../status/status_service.mock'; const MockKbnServer: jest.Mock = KbnServer as any; @@ -106,6 +107,7 @@ beforeEach(() => { rendering: renderingServiceMock, metrics: metricsServiceMock.createInternalSetupContract(), uuid: uuidSetup, + status: statusServiceMock.createInternalSetupContract(), }, plugins: { 'plugin-id': 'plugin-value' }, }; diff --git a/src/core/server/legacy/legacy_service.ts b/src/core/server/legacy/legacy_service.ts index bb5f6d5617aae..f77230301ce02 100644 --- a/src/core/server/legacy/legacy_service.ts +++ b/src/core/server/legacy/legacy_service.ts @@ -306,6 +306,9 @@ export class LegacyService implements CoreService { registerType: setupDeps.core.savedObjects.registerType, getImportExportObjectLimit: setupDeps.core.savedObjects.getImportExportObjectLimit, }, + status: { + core$: setupDeps.core.status.core$, + }, uiSettings: { register: setupDeps.core.uiSettings.register, }, diff --git a/src/core/server/mocks.ts b/src/core/server/mocks.ts index 31bf17da041af..faf73044cac4d 100644 --- a/src/core/server/mocks.ts +++ b/src/core/server/mocks.ts @@ -33,6 +33,7 @@ import { InternalCoreSetup, InternalCoreStart } from './internal_types'; import { capabilitiesServiceMock } from './capabilities/capabilities_service.mock'; import { metricsServiceMock } from './metrics/metrics_service.mock'; import { uuidServiceMock } from './uuid/uuid_service.mock'; +import { statusServiceMock } from './status/status_service.mock'; export { httpServerMock } from './http/http_server.mocks'; export { sessionStorageMock } from './http/cookie_session_storage.mocks'; @@ -133,9 +134,10 @@ function createCoreSetupMock({ elasticsearch: elasticsearchServiceMock.createSetup(), http: httpMock, savedObjects: savedObjectsServiceMock.createInternalSetupContract(), + status: statusServiceMock.createSetupContract(), + metrics: metricsServiceMock.createSetupContract(), uiSettings: uiSettingsMock, uuid: uuidServiceMock.createSetupContract(), - metrics: metricsServiceMock.createSetupContract(), getStartServices: jest .fn, object, any]>, []>() .mockResolvedValue([createCoreStartMock(), pluginStartDeps, pluginStartContract]), @@ -161,10 +163,11 @@ function createInternalCoreSetupMock() { context: contextServiceMock.createSetupContract(), elasticsearch: elasticsearchServiceMock.createInternalSetup(), http: httpServiceMock.createSetupContract(), - uiSettings: uiSettingsServiceMock.createSetupContract(), + metrics: metricsServiceMock.createInternalSetupContract(), savedObjects: savedObjectsServiceMock.createInternalSetupContract(), + status: statusServiceMock.createInternalSetupContract(), uuid: uuidServiceMock.createSetupContract(), - metrics: metricsServiceMock.createInternalSetupContract(), + uiSettings: uiSettingsServiceMock.createSetupContract(), }; return setupDeps; } diff --git a/src/core/server/plugins/plugin_context.ts b/src/core/server/plugins/plugin_context.ts index 32662f07a86f0..61d97aea97459 100644 --- a/src/core/server/plugins/plugin_context.ts +++ b/src/core/server/plugins/plugin_context.ts @@ -175,6 +175,9 @@ export function createPluginSetupContext( registerType: deps.savedObjects.registerType, getImportExportObjectLimit: deps.savedObjects.getImportExportObjectLimit, }, + status: { + core$: deps.status.core$, + }, uiSettings: { register: deps.uiSettings.register, }, diff --git a/src/core/server/saved_objects/index.ts b/src/core/server/saved_objects/index.ts index b50e47b9eab73..fe4795cad11a5 100644 --- a/src/core/server/saved_objects/index.ts +++ b/src/core/server/saved_objects/index.ts @@ -68,7 +68,11 @@ export { SavedObjectMigrationContext, } from './migrations'; -export { SavedObjectsType, SavedObjectsTypeManagementDefinition } from './types'; +export { + SavedObjectStatusMeta, + SavedObjectsType, + SavedObjectsTypeManagementDefinition, +} from './types'; export { savedObjectsConfig, savedObjectsMigrationConfig } from './saved_objects_config'; export { SavedObjectTypeRegistry, ISavedObjectTypeRegistry } from './saved_objects_type_registry'; diff --git a/src/core/server/saved_objects/migrations/core/index.ts b/src/core/server/saved_objects/migrations/core/index.ts index 4fbadf90f4b60..466d399f653cd 100644 --- a/src/core/server/saved_objects/migrations/core/index.ts +++ b/src/core/server/saved_objects/migrations/core/index.ts @@ -22,4 +22,4 @@ export { IndexMigrator } from './index_migrator'; export { buildActiveMappings } from './build_active_mappings'; export { CallCluster } from './call_cluster'; export { LogFn } from './migration_logger'; -export { MigrationResult } from './migration_coordinator'; +export { MigrationResult, MigrationStatus } from './migration_coordinator'; diff --git a/src/core/server/saved_objects/migrations/core/migration_coordinator.ts b/src/core/server/saved_objects/migrations/core/migration_coordinator.ts index ddd82edd93448..5ba2d0afc692e 100644 --- a/src/core/server/saved_objects/migrations/core/migration_coordinator.ts +++ b/src/core/server/saved_objects/migrations/core/migration_coordinator.ts @@ -39,6 +39,8 @@ import { SavedObjectsMigrationLogger } from './migration_logger'; const DEFAULT_POLL_INTERVAL = 15000; +export type MigrationStatus = 'waiting' | 'running' | 'completed'; + export type MigrationResult = | { status: 'skipped' } | { status: 'patched' } diff --git a/src/core/server/saved_objects/migrations/index.ts b/src/core/server/saved_objects/migrations/index.ts index dc966f0797822..8ddaed3707eb0 100644 --- a/src/core/server/saved_objects/migrations/index.ts +++ b/src/core/server/saved_objects/migrations/index.ts @@ -17,6 +17,7 @@ * under the License. */ +export { MigrationResult } from './core'; export { KibanaMigrator, IKibanaMigrator } from './kibana'; export { SavedObjectMigrationFn, diff --git a/src/core/server/saved_objects/migrations/kibana/index.ts b/src/core/server/saved_objects/migrations/kibana/index.ts index 25772c4c9b0b1..df4751521ac53 100644 --- a/src/core/server/saved_objects/migrations/kibana/index.ts +++ b/src/core/server/saved_objects/migrations/kibana/index.ts @@ -17,4 +17,4 @@ * under the License. */ -export { KibanaMigrator, IKibanaMigrator } from './kibana_migrator'; +export { KibanaMigrator, IKibanaMigrator, KibanaMigratorStatus } from './kibana_migrator'; diff --git a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.mock.ts b/src/core/server/saved_objects/migrations/kibana/kibana_migrator.mock.ts index 2ee656721abd0..257b32c1e4c23 100644 --- a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.mock.ts +++ b/src/core/server/saved_objects/migrations/kibana/kibana_migrator.mock.ts @@ -17,10 +17,11 @@ * under the License. */ -import { KibanaMigrator } from './kibana_migrator'; +import { KibanaMigrator, KibanaMigratorStatus } from './kibana_migrator'; import { buildActiveMappings } from '../core'; const { mergeTypes } = jest.requireActual('./kibana_migrator'); import { SavedObjectsType } from '../../types'; +import { BehaviorSubject } from 'rxjs'; const defaultSavedObjectTypes: SavedObjectsType[] = [ { @@ -47,6 +48,20 @@ const createMigrator = ( runMigrations: jest.fn(), getActiveMappings: jest.fn(), migrateDocument: jest.fn(), + getStatus$: jest.fn( + () => + new BehaviorSubject({ + status: 'completed', + result: [ + { + status: 'migrated', + destIndex: '.test-kibana_2', + sourceIndex: '.test-kibana_1', + elapsedMs: 10, + }, + ], + }) + ), }; mockMigrator.getActiveMappings.mockReturnValue(buildActiveMappings(mergeTypes(types))); diff --git a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.test.ts b/src/core/server/saved_objects/migrations/kibana/kibana_migrator.test.ts index fd82bf282266e..336eeff99f47b 100644 --- a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.test.ts +++ b/src/core/server/saved_objects/migrations/kibana/kibana_migrator.test.ts @@ -16,6 +16,7 @@ * specific language governing permissions and limitations * under the License. */ +import { take } from 'rxjs/operators'; import { KibanaMigratorOptions, KibanaMigrator } from './kibana_migrator'; import { loggingServiceMock } from '../../../logging/logging_service.mock'; @@ -79,6 +80,33 @@ describe('KibanaMigrator', () => { .filter(callClusterPath => callClusterPath === 'cat.templates'); expect(callClusterCommands.length).toBe(1); }); + + it('emits results on getMigratorResult$()', async () => { + const options = mockOptions(); + const clusterStub = jest.fn(() => ({ status: 404 })); + + options.callCluster = clusterStub; + const migrator = new KibanaMigrator(options); + const migratorStatus = migrator + .getStatus$() + .pipe(take(3)) + .toPromise(); + await migrator.runMigrations(); + const { status, result } = await migratorStatus; + expect(status).toEqual('completed'); + expect(result![0]).toMatchObject({ + destIndex: '.my-index_1', + elapsedMs: expect.any(Number), + sourceIndex: '.my-index', + status: 'migrated', + }); + expect(result![1]).toMatchObject({ + destIndex: 'other-index_1', + elapsedMs: expect.any(Number), + sourceIndex: 'other-index', + status: 'migrated', + }); + }); }); }); diff --git a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts b/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts index bc29061b380b8..dafd6c5341196 100644 --- a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts +++ b/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts @@ -24,10 +24,17 @@ import { Logger } from 'src/core/server/logging'; import { KibanaConfigType } from 'src/core/server/kibana_config'; +import { BehaviorSubject } from 'rxjs'; import { IndexMapping, SavedObjectsTypeMappingDefinitions } from '../../mappings'; import { SavedObjectUnsanitizedDoc, SavedObjectsSerializer } from '../../serialization'; import { docValidator, PropertyValidators } from '../../validation'; -import { buildActiveMappings, CallCluster, IndexMigrator } from '../core'; +import { + buildActiveMappings, + CallCluster, + IndexMigrator, + MigrationResult, + MigrationStatus, +} from '../core'; import { DocumentMigrator, VersionedTransformer } from '../core/document_migrator'; import { createIndexMap } from '../core/build_index_map'; import { SavedObjectsMigrationConfigType } from '../../saved_objects_config'; @@ -46,6 +53,11 @@ export interface KibanaMigratorOptions { export type IKibanaMigrator = Pick; +export interface KibanaMigratorStatus { + status: MigrationStatus; + result?: MigrationResult[]; +} + /** * Manages the shape of mappings and documents in the Kibana index. */ @@ -58,7 +70,10 @@ export class KibanaMigrator { private readonly mappingProperties: SavedObjectsTypeMappingDefinitions; private readonly typeRegistry: ISavedObjectTypeRegistry; private readonly serializer: SavedObjectsSerializer; - private migrationResult?: Promise>; + private migrationResult?: Promise; + private readonly status$ = new BehaviorSubject({ + status: 'waiting', + }); /** * Creates an instance of KibanaMigrator. @@ -109,12 +124,20 @@ export class KibanaMigrator { Array<{ status: string }> > { if (this.migrationResult === undefined || rerun) { - this.migrationResult = this.runMigrationsInternal(); + this.status$.next({ status: 'running' }); + this.migrationResult = this.runMigrationsInternal().then(result => { + this.status$.next({ status: 'completed', result }); + return result; + }); } return this.migrationResult; } + public getStatus$() { + return this.status$.asObservable(); + } + private runMigrationsInternal() { const kibanaIndexName = this.kibanaConfig.index; const indexMap = createIndexMap({ diff --git a/src/core/server/saved_objects/saved_objects_service.mock.ts b/src/core/server/saved_objects/saved_objects_service.mock.ts index 9fe32b14e6450..7ba4613c857d7 100644 --- a/src/core/server/saved_objects/saved_objects_service.mock.ts +++ b/src/core/server/saved_objects/saved_objects_service.mock.ts @@ -17,6 +17,8 @@ * under the License. */ +import { BehaviorSubject } from 'rxjs'; + import { SavedObjectsService, InternalSavedObjectsServiceSetup, @@ -29,6 +31,7 @@ import { savedObjectsClientProviderMock } from './service/lib/scoped_client_prov import { savedObjectsRepositoryMock } from './service/lib/repository.mock'; import { savedObjectsClientMock } from './service/saved_objects_client.mock'; import { typeRegistryMock } from './saved_objects_type_registry.mock'; +import { ServiceStatusLevels } from '../status'; type SavedObjectsServiceContract = PublicMethodsOf; @@ -75,6 +78,10 @@ const createSetupContractMock = () => { const createInternalSetupContractMock = () => { const internalSetupContract: jest.Mocked = { ...createSetupContractMock(), + status$: new BehaviorSubject({ + level: ServiceStatusLevels.available, + summary: `SavedObjects is available`, + }), }; return internalSetupContract; }; diff --git a/src/core/server/saved_objects/saved_objects_service.ts b/src/core/server/saved_objects/saved_objects_service.ts index aa440c6454569..62027928c0bb5 100644 --- a/src/core/server/saved_objects/saved_objects_service.ts +++ b/src/core/server/saved_objects/saved_objects_service.ts @@ -17,8 +17,8 @@ * under the License. */ -import { Subject } from 'rxjs'; -import { first, filter, take } from 'rxjs/operators'; +import { Subject, Observable } from 'rxjs'; +import { first, filter, take, switchMap } from 'rxjs/operators'; import { CoreService } from '../../types'; import { SavedObjectsClient, @@ -38,7 +38,7 @@ import { SavedObjectConfig, } from './saved_objects_config'; import { KibanaRequest, InternalHttpServiceSetup } from '../http'; -import { SavedObjectsClientContract, SavedObjectsType } from './types'; +import { SavedObjectsClientContract, SavedObjectsType, SavedObjectStatusMeta } from './types'; import { ISavedObjectsRepository, SavedObjectsRepository } from './service/lib/repository'; import { SavedObjectsClientFactoryProvider, @@ -50,6 +50,8 @@ import { SavedObjectTypeRegistry, ISavedObjectTypeRegistry } from './saved_objec import { PropertyValidators } from './validation'; import { SavedObjectsSerializer } from './serialization'; import { registerRoutes } from './routes'; +import { ServiceStatus } from '../status'; +import { calculateStatus$ } from './status'; /** * Saved Objects is Kibana's data persistence mechanism allowing plugins to @@ -164,7 +166,9 @@ export interface SavedObjectsServiceSetup { /** * @internal */ -export type InternalSavedObjectsServiceSetup = SavedObjectsServiceSetup; +export interface InternalSavedObjectsServiceSetup extends SavedObjectsServiceSetup { + status$: Observable>; +} /** * Saved Objects is Kibana's data persisentence mechanism allowing plugins to @@ -321,6 +325,10 @@ export class SavedObjectsService }); return { + status$: calculateStatus$( + this.migrator$.pipe(switchMap(migrator => migrator.getStatus$())), + setupDeps.elasticsearch.status$ + ), setClientFactoryProvider: provider => { if (this.started) { throw new Error('cannot call `setClientFactoryProvider` after service startup.'); diff --git a/src/core/server/saved_objects/status.test.ts b/src/core/server/saved_objects/status.test.ts new file mode 100644 index 0000000000000..8efea1e2c00c6 --- /dev/null +++ b/src/core/server/saved_objects/status.test.ts @@ -0,0 +1,134 @@ +/* + * 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 { of, Observable } from 'rxjs'; +import { ServiceStatus, ServiceStatusLevels } from '../status'; +import { calculateStatus$ } from './status'; +import { take } from 'rxjs/operators'; + +describe('calculateStatus$', () => { + const expectUnavailableDueToEs = (status$: Observable) => + expect(status$.pipe(take(1)).toPromise()).resolves.toEqual({ + level: ServiceStatusLevels.unavailable, + summary: `SavedObjects service is not available without a healthy Elasticearch connection`, + }); + + const expectUnavailableDueToMigrations = (status$: Observable) => + expect(status$.pipe(take(1)).toPromise()).resolves.toEqual({ + level: ServiceStatusLevels.unavailable, + summary: `SavedObjects service is waiting to start migrations`, + }); + + describe('when elasticsearch is unavailable', () => { + const esStatus$ = of({ + level: ServiceStatusLevels.unavailable, + summary: 'xxx', + }); + + it('is unavailable before migrations have ran', async () => { + await expectUnavailableDueToEs(calculateStatus$(of(), esStatus$)); + }); + it('is unavailable after migrations have ran', async () => { + await expectUnavailableDueToEs( + calculateStatus$(of({ status: 'completed', result: [] }), esStatus$) + ); + }); + }); + + describe('when elasticsearch is critical', () => { + const esStatus$ = of({ + level: ServiceStatusLevels.critical, + summary: 'xxx', + }); + + it('is unavailable before migrations have ran', async () => { + await expectUnavailableDueToEs(calculateStatus$(of(), esStatus$)); + }); + it('is unavailable after migrations have ran', async () => { + await expectUnavailableDueToEs( + calculateStatus$( + of({ status: 'completed', result: [{ status: 'migrated' } as any] }), + esStatus$ + ) + ); + }); + }); + + describe('when elasticsearch is available', () => { + const esStatus$ = of({ + level: ServiceStatusLevels.available, + summary: 'Available', + }); + + it('is unavailable before migrations have ran', async () => { + await expectUnavailableDueToMigrations(calculateStatus$(of(), esStatus$)); + }); + it('is unavailable while migrations are running', async () => { + await expect( + calculateStatus$(of({ status: 'running' }), esStatus$) + .pipe(take(2)) + .toPromise() + ).resolves.toEqual({ + level: ServiceStatusLevels.unavailable, + summary: `SavedObjects service is running migrations`, + }); + }); + it('is available after migrations have ran', async () => { + await expect( + calculateStatus$( + of({ status: 'completed', result: [{ status: 'skipped' }, { status: 'patched' }] }), + esStatus$ + ) + .pipe(take(2)) + .toPromise() + ).resolves.toEqual({ + level: ServiceStatusLevels.available, + summary: `SavedObjects service has completed migrations and is available`, + meta: { + migratedIndices: { + migrated: 0, + patched: 1, + skipped: 1, + }, + }, + }); + }); + }); + + describe('when elasticsearch is degraded', () => { + const esStatus$ = of({ level: ServiceStatusLevels.degraded, summary: 'xxx' }); + + it('is unavailable before migrations have ran', async () => { + await expectUnavailableDueToMigrations(calculateStatus$(of(), esStatus$)); + }); + it('is degraded after migrations have ran', async () => { + await expect( + calculateStatus$( + of([{ status: 'skipped' }]), + esStatus$ + ) + .pipe(take(2)) + .toPromise() + ).resolves.toEqual({ + level: ServiceStatusLevels.degraded, + summary: 'SavedObjects service is degraded due to Elasticsearch: [xxx]', + }); + }); + }); +}); diff --git a/src/core/server/saved_objects/status.ts b/src/core/server/saved_objects/status.ts new file mode 100644 index 0000000000000..66a6e2baa17a7 --- /dev/null +++ b/src/core/server/saved_objects/status.ts @@ -0,0 +1,84 @@ +/* + * 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 { Observable, combineLatest } from 'rxjs'; +import { startWith, map } from 'rxjs/operators'; +import { ServiceStatus, ServiceStatusLevels } from '../status'; +import { SavedObjectStatusMeta } from './types'; +import { KibanaMigratorStatus } from './migrations/kibana'; + +export const calculateStatus$ = ( + rawMigratorStatus$: Observable, + elasticsearchStatus$: Observable +): Observable> => { + const migratorStatus$: Observable> = rawMigratorStatus$.pipe( + map(migrationStatus => { + if (migrationStatus.status === 'waiting') { + return { + level: ServiceStatusLevels.unavailable, + summary: `SavedObjects service is waiting to start migrations`, + }; + } else if (migrationStatus.status === 'running') { + return { + level: ServiceStatusLevels.unavailable, + summary: `SavedObjects service is running migrations`, + }; + } + + const statusCounts: SavedObjectStatusMeta['migratedIndices'] = { migrated: 0, skipped: 0 }; + if (migrationStatus.result) { + migrationStatus.result.forEach(({ status }) => { + statusCounts[status] = (statusCounts[status] ?? 0) + 1; + }); + } + + return { + level: ServiceStatusLevels.available, + summary: `SavedObjects service has completed migrations and is available`, + meta: { + migratedIndices: statusCounts, + }, + }; + }), + startWith({ + level: ServiceStatusLevels.unavailable, + summary: `SavedObjects service is waiting to start migrations`, + }) + ); + + return combineLatest([elasticsearchStatus$, migratorStatus$]).pipe( + map(([esStatus, migratorStatus]) => { + if (esStatus.level >= ServiceStatusLevels.unavailable) { + return { + level: ServiceStatusLevels.unavailable, + summary: `SavedObjects service is not available without a healthy Elasticearch connection`, + }; + } else if (migratorStatus.level === ServiceStatusLevels.unavailable) { + return migratorStatus; + } else if (esStatus.level === ServiceStatusLevels.degraded) { + return { + level: esStatus.level, + summary: `SavedObjects service is degraded due to Elasticsearch: [${esStatus.summary}]`, + }; + } else { + return migratorStatus; + } + }) + ); +}; diff --git a/src/core/server/saved_objects/types.ts b/src/core/server/saved_objects/types.ts index 962965a08f8b2..f14e9d9efb5e3 100644 --- a/src/core/server/saved_objects/types.ts +++ b/src/core/server/saved_objects/types.ts @@ -46,6 +46,19 @@ export { SavedObjectsMigrationVersion, } from '../../types'; +/** + * Meta information about the SavedObjectService's status. Available to plugins via {@link CoreSetup.status}. + * + * @public + */ +export interface SavedObjectStatusMeta { + migratedIndices: { + [status: string]: number; + skipped: number; + migrated: number; + }; +} + /** * * @public diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md index e4e2b8d7adbb7..f3e3b7736d8d3 100644 --- a/src/core/server/server.api.md +++ b/src/core/server/server.api.md @@ -638,6 +638,8 @@ export interface CoreSetup ISavedObjectTypeRegistry; } +// @public +export interface SavedObjectStatusMeta { + // (undocumented) + migratedIndices: { + [status: string]: number; + skipped: number; + migrated: number; + }; +} + // @public (undocumented) export interface SavedObjectsType { convertToAliasScript?: string; @@ -2237,6 +2283,38 @@ export class ScopedClusterClient implements IScopedClusterClient { callAsInternalUser(endpoint: string, clientParams?: Record, options?: CallAPIOptions): Promise; } +// @public +export interface ServiceStatus | unknown = unknown> { + detail?: string; + documentationUrl?: string; + level: ServiceStatusLevel; + meta?: Meta; + summary: string; +} + +// @public +export type ServiceStatusLevel = typeof ServiceStatusLevels[keyof typeof ServiceStatusLevels]; + +// @public +export const ServiceStatusLevels: Readonly<{ + available: Readonly<{ + toString: () => "available"; + valueOf: () => 0; + }>; + degraded: Readonly<{ + toString: () => "degraded"; + valueOf: () => 1; + }>; + unavailable: Readonly<{ + toString: () => "unavailable"; + valueOf: () => 2; + }>; + critical: Readonly<{ + toString: () => "critical"; + valueOf: () => 3; + }>; +}>; + // @public export interface SessionCookieValidationResult { isValid: boolean; @@ -2274,6 +2352,11 @@ export type SharedGlobalConfig = RecursiveReadonly_2<{ // @public export type StartServicesAccessor = () => Promise<[CoreStart, TPluginsStart, TStart]>; +// @public +export interface StatusServiceSetup { + core$: Observable; +} + // @public export type StringValidation = StringValidationRegex | StringValidationRegexString; diff --git a/src/core/server/server.test.mocks.ts b/src/core/server/server.test.mocks.ts index 53d1b742a6494..5d535c9845724 100644 --- a/src/core/server/server.test.mocks.ts +++ b/src/core/server/server.test.mocks.ts @@ -85,3 +85,9 @@ export const mockMetricsService = metricsServiceMock.create(); jest.doMock('./metrics/metrics_service', () => ({ MetricsService: jest.fn(() => mockMetricsService), })); + +import { statusServiceMock } from './status/status_service.mock'; +export const mockStatusService = statusServiceMock.create(); +jest.doMock('./status/status_service', () => ({ + StatusService: jest.fn(() => mockStatusService), +})); diff --git a/src/core/server/server.test.ts b/src/core/server/server.test.ts index a4b5a9d81df20..24c41d511180a 100644 --- a/src/core/server/server.test.ts +++ b/src/core/server/server.test.ts @@ -29,6 +29,7 @@ import { mockUiSettingsService, mockRenderingService, mockMetricsService, + mockStatusService, } from './server.test.mocks'; import { BehaviorSubject } from 'rxjs'; @@ -63,6 +64,7 @@ test('sets up services on "setup"', async () => { expect(mockUiSettingsService.setup).not.toHaveBeenCalled(); expect(mockRenderingService.setup).not.toHaveBeenCalled(); expect(mockMetricsService.setup).not.toHaveBeenCalled(); + expect(mockStatusService.setup).not.toHaveBeenCalled(); await server.setup(); @@ -74,6 +76,7 @@ test('sets up services on "setup"', async () => { expect(mockUiSettingsService.setup).toHaveBeenCalledTimes(1); expect(mockRenderingService.setup).toHaveBeenCalledTimes(1); expect(mockMetricsService.setup).toHaveBeenCalledTimes(1); + expect(mockStatusService.setup).toHaveBeenCalledTimes(1); }); test('injects legacy dependency to context#setup()', async () => { @@ -141,6 +144,7 @@ test('stops services on "stop"', async () => { expect(mockSavedObjectsService.stop).not.toHaveBeenCalled(); expect(mockUiSettingsService.stop).not.toHaveBeenCalled(); expect(mockMetricsService.stop).not.toHaveBeenCalled(); + expect(mockStatusService.stop).not.toHaveBeenCalled(); await server.stop(); @@ -151,6 +155,7 @@ test('stops services on "stop"', async () => { expect(mockSavedObjectsService.stop).toHaveBeenCalledTimes(1); expect(mockUiSettingsService.stop).toHaveBeenCalledTimes(1); expect(mockMetricsService.stop).toHaveBeenCalledTimes(1); + expect(mockStatusService.stop).toHaveBeenCalledTimes(1); }); test(`doesn't setup core services if config validation fails`, async () => { @@ -167,6 +172,7 @@ test(`doesn't setup core services if config validation fails`, async () => { expect(mockUiSettingsService.setup).not.toHaveBeenCalled(); expect(mockRenderingService.setup).not.toHaveBeenCalled(); expect(mockMetricsService.setup).not.toHaveBeenCalled(); + expect(mockStatusService.setup).not.toHaveBeenCalled(); }); test(`doesn't setup core services if legacy config validation fails`, async () => { @@ -187,4 +193,5 @@ test(`doesn't setup core services if legacy config validation fails`, async () = expect(mockSavedObjectsService.stop).not.toHaveBeenCalled(); expect(mockUiSettingsService.setup).not.toHaveBeenCalled(); expect(mockMetricsService.setup).not.toHaveBeenCalled(); + expect(mockStatusService.setup).not.toHaveBeenCalled(); }); diff --git a/src/core/server/server.ts b/src/core/server/server.ts index 222be572b75e4..07ea431dd3a0d 100644 --- a/src/core/server/server.ts +++ b/src/core/server/server.ts @@ -36,6 +36,9 @@ import { UiSettingsService } from './ui_settings'; import { PluginsService, config as pluginsConfig } from './plugins'; import { SavedObjectsService } from '../server/saved_objects'; import { MetricsService, opsConfig } from './metrics'; +import { CapabilitiesService } from './capabilities'; +import { UuidService } from './uuid'; +import { StatusService } from './status/status_service'; import { config as cspConfig } from './csp'; import { config as elasticsearchConfig } from './elasticsearch'; @@ -50,8 +53,6 @@ import { mapToObject } from '../utils'; import { ContextService } from './context'; import { RequestHandlerContext } from '.'; import { InternalCoreSetup, InternalCoreStart } from './internal_types'; -import { CapabilitiesService } from './capabilities'; -import { UuidService } from './uuid'; const coreId = Symbol('core'); const rootConfigPath = ''; @@ -70,6 +71,7 @@ export class Server { private readonly uiSettings: UiSettingsService; private readonly uuid: UuidService; private readonly metrics: MetricsService; + private readonly status: StatusService; private readonly coreApp: CoreApp; private pluginsInitialized?: boolean; @@ -95,6 +97,7 @@ export class Server { this.capabilities = new CapabilitiesService(core); this.uuid = new UuidService(core); this.metrics = new MetricsService(core); + this.status = new StatusService(core); this.coreApp = new CoreApp(core); } @@ -145,15 +148,21 @@ export class Server { const metricsSetup = await this.metrics.setup({ http: httpSetup }); + const statusSetup = this.status.setup({ + elasticsearch: elasticsearchServiceSetup, + savedObjects: savedObjectsSetup, + }); + const coreSetup: InternalCoreSetup = { capabilities: capabilitiesSetup, context: contextServiceSetup, elasticsearch: elasticsearchServiceSetup, http: httpSetup, - uiSettings: uiSettingsSetup, + metrics: metricsSetup, savedObjects: savedObjectsSetup, + status: statusSetup, + uiSettings: uiSettingsSetup, uuid: uuidSetup, - metrics: metricsSetup, }; const pluginsSetup = await this.plugins.setup(coreSetup); @@ -220,6 +229,7 @@ export class Server { await this.uiSettings.stop(); await this.rendering.stop(); await this.metrics.stop(); + await this.status.stop(); } private registerCoreContext(coreSetup: InternalCoreSetup, rendering: RenderingServiceSetup) { diff --git a/src/core/server/status/get_summary_status.test.ts b/src/core/server/status/get_summary_status.test.ts new file mode 100644 index 0000000000000..7516e82ee784d --- /dev/null +++ b/src/core/server/status/get_summary_status.test.ts @@ -0,0 +1,180 @@ +/* + * 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 { ServiceStatus, ServiceStatusLevels } from './types'; +import { getSummaryStatus } from './get_summary_status'; + +describe('getSummaryStatus', () => { + const available: ServiceStatus = { level: ServiceStatusLevels.available, summary: 'Available' }; + const degraded: ServiceStatus = { + level: ServiceStatusLevels.degraded, + summary: 'This is degraded!', + }; + const unavailable: ServiceStatus = { + level: ServiceStatusLevels.unavailable, + summary: 'This is unavailable!', + }; + const critical: ServiceStatus = { + level: ServiceStatusLevels.critical, + summary: 'This is critical!', + }; + + it('returns available when all status are available', () => { + expect( + getSummaryStatus( + Object.entries({ + s1: available, + s2: available, + s3: available, + }) + ) + ).toMatchObject({ + level: ServiceStatusLevels.available, + }); + }); + + it('returns degraded when the worst status is degraded', () => { + expect( + getSummaryStatus( + Object.entries({ + s1: available, + s2: degraded, + s3: available, + }) + ) + ).toMatchObject({ + level: ServiceStatusLevels.degraded, + }); + }); + + it('returns unavailable when the worst status is unavailable', () => { + expect( + getSummaryStatus( + Object.entries({ + s1: available, + s2: degraded, + s3: unavailable, + }) + ) + ).toMatchObject({ + level: ServiceStatusLevels.unavailable, + }); + }); + + it('returns critical when the worst status is critical', () => { + expect( + getSummaryStatus( + Object.entries({ + s1: critical, + s2: degraded, + s3: unavailable, + }) + ) + ).toMatchObject({ + level: ServiceStatusLevels.critical, + }); + }); + + describe('summary', () => { + describe('when a single service is at highest level', () => { + it('returns all information about that single service', () => { + expect( + getSummaryStatus( + Object.entries({ + s1: degraded, + s2: { + level: ServiceStatusLevels.unavailable, + summary: 'Lorem ipsum', + detail: 'Vivamus pulvinar sem ac luctus ultrices.', + documentationUrl: 'http://helpmenow.com/problem1', + meta: { + custom: { data: 'here' }, + }, + }, + }) + ) + ).toEqual({ + level: ServiceStatusLevels.unavailable, + summary: '[s2]: Lorem ipsum', + detail: 'Vivamus pulvinar sem ac luctus ultrices.', + documentationUrl: 'http://helpmenow.com/problem1', + meta: { + custom: { data: 'here' }, + }, + }); + }); + }); + + describe('when multiple services is at highest level', () => { + it('returns aggregated information about the affected services', () => { + expect( + getSummaryStatus( + Object.entries({ + s1: degraded, + s2: { + level: ServiceStatusLevels.unavailable, + summary: 'Lorem ipsum', + detail: 'Vivamus pulvinar sem ac luctus ultrices.', + documentationUrl: 'http://helpmenow.com/problem1', + meta: { + custom: { data: 'here' }, + }, + }, + s3: { + level: ServiceStatusLevels.unavailable, + summary: 'Proin mattis', + detail: 'Nunc quis nulla at mi lobortis pretium.', + documentationUrl: 'http://helpmenow.com/problem2', + meta: { + other: { data: 'over there' }, + }, + }, + }) + ) + ).toEqual({ + level: ServiceStatusLevels.unavailable, + summary: '[2] services are unavailable', + detail: 'See the status page for more information', + meta: { + affectedServices: { + s2: { + level: ServiceStatusLevels.unavailable, + summary: 'Lorem ipsum', + detail: 'Vivamus pulvinar sem ac luctus ultrices.', + documentationUrl: 'http://helpmenow.com/problem1', + meta: { + custom: { data: 'here' }, + }, + }, + s3: { + level: ServiceStatusLevels.unavailable, + summary: 'Proin mattis', + detail: 'Nunc quis nulla at mi lobortis pretium.', + documentationUrl: 'http://helpmenow.com/problem2', + meta: { + other: { data: 'over there' }, + }, + }, + }, + }, + }); + }); + }); + }); +}); diff --git a/src/core/server/status/get_summary_status.ts b/src/core/server/status/get_summary_status.ts new file mode 100644 index 0000000000000..748a54f0bf8bb --- /dev/null +++ b/src/core/server/status/get_summary_status.ts @@ -0,0 +1,84 @@ +/* + * 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 { ServiceStatus, ServiceStatusLevels, ServiceStatusLevel } from './types'; + +/** + * Returns a single {@link ServiceStatus} that summarizes the most severe status level from a group of statuses. + * @param statuses + */ +export const getSummaryStatus = (statuses: Array<[string, ServiceStatus]>): ServiceStatus => { + const grouped = groupByLevel(statuses); + const highestSeverityLevel = getHighestSeverityLevel(grouped.keys()); + const highestSeverityGroup = grouped.get(highestSeverityLevel)!; + + if (highestSeverityLevel === ServiceStatusLevels.available) { + return { + level: ServiceStatusLevels.available, + summary: `All services are available`, + }; + } else if (highestSeverityGroup.size === 1) { + const [serviceName, status] = [...highestSeverityGroup.entries()][0]; + return { + ...status, + summary: `[${serviceName}]: ${status.summary!}`, + }; + } else { + return { + level: highestSeverityLevel, + summary: `[${highestSeverityGroup.size}] services are ${highestSeverityLevel.toString()}`, + // TODO: include URL to status page + detail: `See the status page for more information`, + meta: { + affectedServices: Object.fromEntries([...highestSeverityGroup]), + }, + }; + } +}; + +const groupByLevel = ( + statuses: Array<[string, ServiceStatus]> +): Map> => { + const byLevel = new Map>(); + + for (const [serviceName, status] of statuses) { + let levelMap = byLevel.get(status.level); + if (!levelMap) { + levelMap = new Map(); + byLevel.set(status.level, levelMap); + } + + levelMap.set(serviceName, status); + } + + return byLevel; +}; + +const getHighestSeverityLevel = (levels: Iterable): ServiceStatusLevel => { + const sorted = [...levels].sort((a, b) => { + if (a < b) { + return -1; + } else if (a > b) { + return 1; + } else { + return 0; + } + }); + return sorted[sorted.length - 1] ?? ServiceStatusLevels.available; +}; diff --git a/src/core/server/status/index.ts b/src/core/server/status/index.ts new file mode 100644 index 0000000000000..c39115d55a682 --- /dev/null +++ b/src/core/server/status/index.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 { StatusService } from './status_service'; +export * from './types'; diff --git a/src/core/server/status/status_service.mock.ts b/src/core/server/status/status_service.mock.ts new file mode 100644 index 0000000000000..d550c2f06750b --- /dev/null +++ b/src/core/server/status/status_service.mock.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 { StatusService } from './status_service'; +import { + InternalStatusServiceSetup, + StatusServiceSetup, + ServiceStatusLevels, + ServiceStatus, + CoreStatus, +} from './types'; +import { BehaviorSubject } from 'rxjs'; + +const available: ServiceStatus = { + level: ServiceStatusLevels.available, + summary: 'Service is working', +}; +const availableCoreStatus: CoreStatus = { + elasticsearch: available, + savedObjects: available, +}; + +const createSetupContractMock = () => { + const setupContract: jest.Mocked = { + core$: new BehaviorSubject(availableCoreStatus), + }; + + return setupContract; +}; + +const createInternalSetupContractMock = () => { + const setupContract: jest.Mocked = { + core$: new BehaviorSubject(availableCoreStatus), + overall$: new BehaviorSubject(available), + }; + + return setupContract; +}; + +type StatusServiceContract = PublicMethodsOf; + +const createMock = () => { + const mocked: jest.Mocked = { + setup: jest.fn().mockReturnValue(createInternalSetupContractMock()), + start: jest.fn(), + stop: jest.fn(), + }; + return mocked; +}; + +export const statusServiceMock = { + create: createMock, + createSetupContract: createSetupContractMock, + createInternalSetupContract: createInternalSetupContractMock, +}; diff --git a/src/core/server/status/status_service.test.ts b/src/core/server/status/status_service.test.ts new file mode 100644 index 0000000000000..6d92a266369b9 --- /dev/null +++ b/src/core/server/status/status_service.test.ts @@ -0,0 +1,229 @@ +/* + * 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 { of, BehaviorSubject } from 'rxjs'; + +import { ServiceStatus, ServiceStatusLevels, CoreStatus } from './types'; +import { StatusService } from './status_service'; +import { first } from 'rxjs/operators'; +import { mockCoreContext } from '../core_context.mock'; +import { ServiceStatusLevelSnapshotSerializer } from './test_utils'; + +expect.addSnapshotSerializer(ServiceStatusLevelSnapshotSerializer); + +describe('StatusService', () => { + const available: ServiceStatus = { + level: ServiceStatusLevels.available, + summary: 'Available', + }; + const degraded: ServiceStatus = { + level: ServiceStatusLevels.degraded, + summary: 'This is degraded!', + }; + + describe('setup', () => { + describe('core$', () => { + it('rolls up core status observables into single observable', async () => { + const setup = new StatusService(mockCoreContext.create()).setup({ + elasticsearch: { + status$: of(available), + }, + savedObjects: { + status$: of(degraded), + }, + }); + expect(await setup.core$.pipe(first()).toPromise()).toEqual({ + elasticsearch: available, + savedObjects: degraded, + }); + }); + + it('replays last event', async () => { + const setup = new StatusService(mockCoreContext.create()).setup({ + elasticsearch: { + status$: of(available), + }, + savedObjects: { + status$: of(degraded), + }, + }); + const subResult1 = await setup.core$.pipe(first()).toPromise(); + const subResult2 = await setup.core$.pipe(first()).toPromise(); + const subResult3 = await setup.core$.pipe(first()).toPromise(); + expect(subResult1).toEqual({ + elasticsearch: available, + savedObjects: degraded, + }); + expect(subResult2).toEqual({ + elasticsearch: available, + savedObjects: degraded, + }); + expect(subResult3).toEqual({ + elasticsearch: available, + savedObjects: degraded, + }); + }); + + it('does not emit duplicate events', () => { + const elasticsearch$ = new BehaviorSubject(available); + const savedObjects$ = new BehaviorSubject(degraded); + const setup = new StatusService(mockCoreContext.create()).setup({ + elasticsearch: { + status$: elasticsearch$, + }, + savedObjects: { + status$: savedObjects$, + }, + }); + + const statusUpdates: CoreStatus[] = []; + const subscription = setup.core$.subscribe(status => statusUpdates.push(status)); + + elasticsearch$.next(available); + elasticsearch$.next(available); + elasticsearch$.next({ + level: ServiceStatusLevels.available, + summary: `Wow another summary`, + }); + savedObjects$.next(degraded); + savedObjects$.next(available); + savedObjects$.next(available); + subscription.unsubscribe(); + + expect(statusUpdates).toMatchInlineSnapshot(` + Array [ + Object { + "elasticsearch": Object { + "level": available, + "summary": "Available", + }, + "savedObjects": Object { + "level": degraded, + "summary": "This is degraded!", + }, + }, + Object { + "elasticsearch": Object { + "level": available, + "summary": "Wow another summary", + }, + "savedObjects": Object { + "level": degraded, + "summary": "This is degraded!", + }, + }, + Object { + "elasticsearch": Object { + "level": available, + "summary": "Wow another summary", + }, + "savedObjects": Object { + "level": available, + "summary": "Available", + }, + }, + ] + `); + }); + }); + + describe('overall$', () => { + it('exposes an overall summary', async () => { + const setup = new StatusService(mockCoreContext.create()).setup({ + elasticsearch: { + status$: of(degraded), + }, + savedObjects: { + status$: of(degraded), + }, + }); + expect(await setup.overall$.pipe(first()).toPromise()).toMatchObject({ + level: ServiceStatusLevels.degraded, + summary: '[2] services are degraded', + }); + }); + + it('replays last event', async () => { + const setup = new StatusService(mockCoreContext.create()).setup({ + elasticsearch: { + status$: of(degraded), + }, + savedObjects: { + status$: of(degraded), + }, + }); + const subResult1 = await setup.overall$.pipe(first()).toPromise(); + const subResult2 = await setup.overall$.pipe(first()).toPromise(); + const subResult3 = await setup.overall$.pipe(first()).toPromise(); + expect(subResult1).toMatchObject({ + level: ServiceStatusLevels.degraded, + summary: '[2] services are degraded', + }); + expect(subResult2).toMatchObject({ + level: ServiceStatusLevels.degraded, + summary: '[2] services are degraded', + }); + expect(subResult3).toMatchObject({ + level: ServiceStatusLevels.degraded, + summary: '[2] services are degraded', + }); + }); + + it('does not emit duplicate events', () => { + const elasticsearch$ = new BehaviorSubject(available); + const savedObjects$ = new BehaviorSubject(degraded); + const setup = new StatusService(mockCoreContext.create()).setup({ + elasticsearch: { + status$: elasticsearch$, + }, + savedObjects: { + status$: savedObjects$, + }, + }); + + const statusUpdates: ServiceStatus[] = []; + const subscription = setup.overall$.subscribe(status => statusUpdates.push(status)); + + elasticsearch$.next(available); + elasticsearch$.next(available); + elasticsearch$.next({ + level: ServiceStatusLevels.available, + summary: `Wow another summary`, + }); + savedObjects$.next(degraded); + savedObjects$.next(available); + savedObjects$.next(available); + subscription.unsubscribe(); + + expect(statusUpdates).toMatchInlineSnapshot(` + Array [ + Object { + "level": degraded, + "summary": "[savedObjects]: This is degraded!", + }, + Object { + "level": available, + "summary": "All services are available", + }, + ] + `); + }); + }); + }); +}); diff --git a/src/core/server/status/status_service.ts b/src/core/server/status/status_service.ts new file mode 100644 index 0000000000000..b6697d8221951 --- /dev/null +++ b/src/core/server/status/status_service.ts @@ -0,0 +1,78 @@ +/* + * 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. + */ + +/* eslint-disable max-classes-per-file */ + +import { Observable, combineLatest } from 'rxjs'; +import { map, distinctUntilChanged, shareReplay } from 'rxjs/operators'; +import { isDeepStrictEqual } from 'util'; + +import { CoreService } from '../../types'; +import { CoreContext } from '../core_context'; +import { Logger } from '../logging'; +import { InternalElasticsearchServiceSetup } from '../elasticsearch'; +import { InternalSavedObjectsServiceSetup } from '../saved_objects'; + +import { ServiceStatus, CoreStatus, InternalStatusServiceSetup } from './types'; +import { getSummaryStatus } from './get_summary_status'; + +interface SetupDeps { + elasticsearch: Pick; + savedObjects: Pick; +} + +export class StatusService implements CoreService { + private readonly logger: Logger; + + constructor(coreContext: CoreContext) { + this.logger = coreContext.logger.get('status'); + } + + public setup(core: SetupDeps) { + const core$ = this.setupCoreStatus(core); + const overall$: Observable = core$.pipe( + map(coreStatus => { + const summary = getSummaryStatus(Object.entries(coreStatus)); + this.logger.debug(`Recalculated overall status`, { status: summary }); + return summary; + }), + distinctUntilChanged(isDeepStrictEqual) + ); + + return { + core$, + overall$, + }; + } + + public start() {} + + public stop() {} + + private setupCoreStatus({ elasticsearch, savedObjects }: SetupDeps): Observable { + return combineLatest([elasticsearch.status$, savedObjects.status$]).pipe( + map(([elasticsearchStatus, savedObjectsStatus]) => ({ + elasticsearch: elasticsearchStatus, + savedObjects: savedObjectsStatus, + })), + distinctUntilChanged(isDeepStrictEqual), + shareReplay(1) + ); + } +} diff --git a/src/core/server/status/test_utils.ts b/src/core/server/status/test_utils.ts new file mode 100644 index 0000000000000..765fa8771f375 --- /dev/null +++ b/src/core/server/status/test_utils.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 { ServiceStatusLevels, ServiceStatusLevel } from './types'; + +export const ServiceStatusLevelSnapshotSerializer: jest.SnapshotSerializerPlugin = { + test: (val: any) => Object.values(ServiceStatusLevels).includes(val), + print: (val: ServiceStatusLevel) => val.toString(), +}; diff --git a/src/core/server/status/types.ts b/src/core/server/status/types.ts new file mode 100644 index 0000000000000..84a7356c66bbf --- /dev/null +++ b/src/core/server/status/types.ts @@ -0,0 +1,134 @@ +/* + * 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 { Observable } from 'rxjs'; +import { deepFreeze } from '../../utils'; + +/** + * The current status of a service at a point in time. + * + * @typeParam Meta - JSON-serializable object. Plugins should export this type to allow other plugins to read the `meta` + * field in a type-safe way. + * @public + */ +export interface ServiceStatus | unknown = unknown> { + /** + * The current availability level of the service. + */ + level: ServiceStatusLevel; + /** + * A high-level summary of the service status. + */ + summary: string; + /** + * A more detailed description of the service status. + */ + detail?: string; + /** + * A URL to open in a new tab about how to resolve or troubleshoot the problem. + */ + documentationUrl?: string; + /** + * Any JSON-serializable data to be included in the HTTP API response. Useful for providing more fine-grained, + * machine-readable information about the service status. May include status information for underlying features. + */ + meta?: Meta; +} + +/** + * The current "level" of availability of a service. + * + * @remarks + * The values implement `valueOf` to allow for easy comparisons between status levels with <, >, etc. Higher values + * represent higher severities. Note that the default `Array.prototype.sort` implementation does not correctly sort + * these values. + * + * A snapshot serializer is available in `src/core/server/test_utils` to ease testing of these values with Jest. + * + * @public + */ +export const ServiceStatusLevels = deepFreeze({ + /** + * Everything is working! + */ + available: { + toString: () => 'available', + valueOf: () => 0, + }, + /** + * Some features may not be working. + */ + degraded: { + toString: () => 'degraded', + valueOf: () => 1, + }, + /** + * The service is unavailable, but other functions that do not depend on this service should work. + */ + unavailable: { + toString: () => 'unavailable', + valueOf: () => 2, + }, + /** + * Block all user functions and display the status page, reserved for Core services only. + */ + critical: { + toString: () => 'critical', + valueOf: () => 3, + }, +}); + +/** + * A convenience type that represents the union of each value in {@link ServiceStatusLevels}. + * @public + */ +export type ServiceStatusLevel = typeof ServiceStatusLevels[keyof typeof ServiceStatusLevels]; + +/** + * Status of core services. + * + * @internalRemarks + * Only contains entries for backend services that could have a non-available `status`. + * For example, `context` cannot possibly be broken, so it is not included. + * + * @public + */ +export interface CoreStatus { + elasticsearch: ServiceStatus; + savedObjects: ServiceStatus; +} + +/** + * API for accessing status of Core and this plugin's dependencies as well as for customizing this plugin's status. + * @public + */ +export interface StatusServiceSetup { + /** + * Current status for all Core services. + */ + core$: Observable; +} + +/** @internal */ +export interface InternalStatusServiceSetup extends StatusServiceSetup { + /** + * Overall system status used for HTTP API + */ + overall$: Observable; +} diff --git a/src/core/server/test_utils.ts b/src/core/server/test_utils.ts index 470b1c2d135b7..f7e6fbcd0c131 100644 --- a/src/core/server/test_utils.ts +++ b/src/core/server/test_utils.ts @@ -18,3 +18,4 @@ */ export { createHttpServer } from './http/test_utils'; +export { ServiceStatusLevelSnapshotSerializer } from './status/test_utils'; From e0a519424fce5758434b914c38d877cbc7588f93 Mon Sep 17 00:00:00 2001 From: Matthew Kime Date: Wed, 8 Apr 2020 15:10:44 -0500 Subject: [PATCH 30/40] Index pattern management plugin - src/legacy/core_plugins/management => new platform plugin (#62594) * implement index pattern management plugin in new platform --- .i18nrc.json | 1 + .../services => kibana/public}/index.ts | 5 +- .../step_index_pattern.test.tsx | 2 +- .../step_index_pattern/step_index_pattern.tsx | 2 +- .../step_time_field/step_time_field.test.tsx | 2 +- .../step_time_field/step_time_field.tsx | 2 +- .../create_index_pattern_wizard/index.js | 3 +- .../lib/get_indices.test.ts | 2 +- .../lib/get_indices.ts | 2 +- .../edit_index_pattern/edit_index_pattern.js | 13 ++--- .../sections/index_patterns/index.js | 5 +- .../__jest__/objects_table.test.js | 4 +- .../components/flyout/__jest__/flyout.test.js | 4 +- src/legacy/core_plugins/management/index.ts | 37 ------------- .../core_plugins/management/package.json | 5 -- .../core_plugins/management/public/index.ts | 38 -------------- .../core_plugins/management/public/legacy.ts | 45 ---------------- .../new_platform/new_platform.karma_mock.js | 15 ++++++ .../ui/public/new_platform/new_platform.ts | 6 +++ .../index_pattern_management/kibana.json | 7 +++ .../index_pattern_management/public}/index.ts | 11 ++-- .../index_pattern_management/public}/mocks.ts | 52 +++++++++---------- .../public}/plugin.ts | 41 +++++++-------- .../public/service}/creation/config.ts | 8 +-- .../public/service}/creation/index.ts | 0 .../public/service}/creation/manager.ts | 21 ++++++-- .../public/service}/index.ts | 0 .../index_pattern_management_service.ts | 51 ++++++++---------- .../public/service}/list/config.ts | 9 ++-- .../public/service}/list/index.ts | 0 .../public/service}/list/manager.ts | 18 +++++-- x-pack/legacy/plugins/rollup/kibana.json | 3 +- .../rollup_index_pattern_creation_config.js | 2 +- .../rollup_index_pattern_list_config.js | 2 +- x-pack/legacy/plugins/rollup/public/legacy.ts | 8 +-- x-pack/legacy/plugins/rollup/public/plugin.ts | 17 ++---- .../components/copy_to_space_flyout.test.tsx | 6 --- .../components/copy_to_space_flyout.tsx | 2 +- .../copy_to_space_flyout_footer.tsx | 2 +- .../components/processing_copy_to_space.tsx | 2 +- .../summarize_copy_result.test.ts | 2 +- .../summarize_copy_result.ts | 2 +- .../translations/translations/ja-JP.json | 10 ++-- .../translations/translations/zh-CN.json | 10 ++-- 44 files changed, 183 insertions(+), 296 deletions(-) rename src/legacy/core_plugins/{management/public/np_ready/services => kibana/public}/index.ts (86%) delete mode 100644 src/legacy/core_plugins/management/index.ts delete mode 100644 src/legacy/core_plugins/management/package.json delete mode 100644 src/legacy/core_plugins/management/public/index.ts delete mode 100644 src/legacy/core_plugins/management/public/legacy.ts create mode 100644 src/plugins/index_pattern_management/kibana.json rename src/{legacy/core_plugins/management/public/np_ready => plugins/index_pattern_management/public}/index.ts (83%) rename src/{legacy/core_plugins/management/public/np_ready => plugins/index_pattern_management/public}/mocks.ts (57%) rename src/{legacy/core_plugins/management/public/np_ready => plugins/index_pattern_management/public}/plugin.ts (60%) rename src/{legacy/core_plugins/management/public/np_ready/services/index_pattern_management => plugins/index_pattern_management/public/service}/creation/config.ts (88%) rename src/{legacy/core_plugins/management/public/np_ready/services/index_pattern_management => plugins/index_pattern_management/public/service}/creation/index.ts (100%) rename src/{legacy/core_plugins/management/public/np_ready/services/index_pattern_management => plugins/index_pattern_management/public/service}/creation/manager.ts (79%) rename src/{legacy/core_plugins/management/public/np_ready/services/index_pattern_management => plugins/index_pattern_management/public/service}/index.ts (100%) rename src/{legacy/core_plugins/management/public/np_ready/services/index_pattern_management => plugins/index_pattern_management/public/service}/index_pattern_management_service.ts (51%) rename src/{legacy/core_plugins/management/public/np_ready/services/index_pattern_management => plugins/index_pattern_management/public/service}/list/config.ts (87%) rename src/{legacy/core_plugins/management/public/np_ready/services/index_pattern_management => plugins/index_pattern_management/public/service}/list/index.ts (100%) rename src/{legacy/core_plugins/management/public/np_ready/services/index_pattern_management => plugins/index_pattern_management/public/service}/list/manager.ts (75%) diff --git a/.i18nrc.json b/.i18nrc.json index 3b0b40b40792e..19d361aed9344 100644 --- a/.i18nrc.json +++ b/.i18nrc.json @@ -24,6 +24,7 @@ "src/legacy/core_plugins/management", "src/plugins/management" ], + "indexPatternManagement": "src/plugins/index_pattern_management", "advancedSettings": "src/plugins/advanced_settings", "kibana_legacy": "src/plugins/kibana_legacy", "kibana_react": "src/legacy/core_plugins/kibana_react", diff --git a/src/legacy/core_plugins/management/public/np_ready/services/index.ts b/src/legacy/core_plugins/kibana/public/index.ts similarity index 86% rename from src/legacy/core_plugins/management/public/np_ready/services/index.ts rename to src/legacy/core_plugins/kibana/public/index.ts index 9df010223542b..a4fffc6eec26d 100644 --- a/src/legacy/core_plugins/management/public/np_ready/services/index.ts +++ b/src/legacy/core_plugins/kibana/public/index.ts @@ -17,4 +17,7 @@ * under the License. */ -export * from './index_pattern_management'; +export { + ProcessedImportResponse, + processImportResponse, +} from './management/sections/objects/lib/process_import_response'; diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/step_index_pattern.test.tsx b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/step_index_pattern.test.tsx index 25bd36829b6d0..40471b95d774c 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/step_index_pattern.test.tsx +++ b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/step_index_pattern.test.tsx @@ -21,7 +21,7 @@ import React from 'react'; import { StepIndexPattern } from '../step_index_pattern'; import { shallowWithI18nProvider } from 'test_utils/enzyme_helpers'; import { Header } from './components/header'; -import { IndexPatternCreationConfig } from '../../../../../../../../management/public'; +import { IndexPatternCreationConfig } from '../../../../../../../../../../plugins/index_pattern_management/public'; import { coreMock } from '../../../../../../../../../../core/public/mocks'; import { dataPluginMock } from '../../../../../../../../../../plugins/data/public/mocks'; import { SavedObjectsFindResponsePublic } from '../../../../../../../../../../core/public'; diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/step_index_pattern.tsx b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/step_index_pattern.tsx index bbb6bf26e5b31..648bf7f8f9738 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/step_index_pattern.tsx +++ b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_index_pattern/step_index_pattern.tsx @@ -39,7 +39,7 @@ import { LoadingIndices } from './components/loading_indices'; import { StatusMessage } from './components/status_message'; import { IndicesList } from './components/indices_list'; import { Header } from './components/header'; -import { IndexPatternCreationConfig } from '../../../../../../../../management/public'; +import { IndexPatternCreationConfig } from '../../../../../../../../../../plugins/index_pattern_management/public'; import { MatchedIndex } from '../../types'; interface StepIndexPatternProps { diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/step_time_field.test.tsx b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/step_time_field.test.tsx index e0c43105cb320..b23b1e3ad9051 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/step_time_field.test.tsx +++ b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/step_time_field.test.tsx @@ -19,7 +19,7 @@ import React from 'react'; import { shallowWithI18nProvider } from 'test_utils/enzyme_helpers'; -import { IndexPatternCreationConfig } from '../../../../../../../../management/public'; +import { IndexPatternCreationConfig } from '../../../../../../../../../../plugins/index_pattern_management/public'; import { IFieldType } from '../../../../../../../../../../plugins/data/public'; import { StepTimeField } from '../step_time_field'; diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/step_time_field.tsx b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/step_time_field.tsx index 80582cc1fbd92..a58bf10c9dab8 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/step_time_field.tsx +++ b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/components/step_time_field/step_time_field.tsx @@ -34,7 +34,7 @@ import { Header } from './components/header'; import { TimeField } from './components/time_field'; import { AdvancedOptions } from './components/advanced_options'; import { ActionButtons } from './components/action_buttons'; -import { IndexPatternCreationConfig } from '../../../../../../../../management/public'; +import { IndexPatternCreationConfig } from '../../../../../../../../../../plugins/index_pattern_management/public'; import { DataPublicPluginStart } from '../../../../../../../../../../plugins/data/public'; interface StepTimeFieldProps { diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/index.js b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/index.js index 50c5a58d35db3..47cb773258cb4 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/index.js +++ b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/index.js @@ -20,7 +20,6 @@ import uiRoutes from 'ui/routes'; import angularTemplate from './angular_template.html'; import { npStart } from 'ui/new_platform'; -import { setup as managementSetup } from '../../../../../../management/public/legacy'; import { getCreateBreadcrumbs } from '../breadcrumbs'; import { renderCreateIndexPatternWizard, destroyCreateIndexPatternWizard } from './render'; @@ -33,7 +32,7 @@ uiRoutes.when('/management/kibana/index_pattern', { const kbnUrl = $injector.get('kbnUrl'); $scope.$$postDigest(() => { const $routeParams = $injector.get('$routeParams'); - const indexPatternCreationType = managementSetup.indexPattern.creation.getType( + const indexPatternCreationType = npStart.plugins.indexPatternManagement.creation.getType( $routeParams.type ); const services = { diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/lib/get_indices.test.ts b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/lib/get_indices.test.ts index 5a8460fcb51ba..40583af7177fe 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/lib/get_indices.test.ts +++ b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/lib/get_indices.test.ts @@ -18,7 +18,7 @@ */ import { getIndices } from './get_indices'; -import { IndexPatternCreationConfig } from './../../../../../../../management/public'; +import { IndexPatternCreationConfig } from '../../../../../../../../../plugins/index_pattern_management/public'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { LegacyApiCaller } from '../../../../../../../../../plugins/data/public/search'; diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/lib/get_indices.ts b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/lib/get_indices.ts index 3848c425e2d49..3b1b7a3b52a5b 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/lib/get_indices.ts +++ b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/lib/get_indices.ts @@ -18,7 +18,7 @@ */ import { get, sortBy } from 'lodash'; -import { IndexPatternCreationConfig } from '../../../../../../../management/public'; +import { IndexPatternCreationConfig } from '../../../../../../../../../plugins/index_pattern_management/public'; import { DataPublicPluginStart } from '../../../../../../../../../plugins/data/public'; import { MatchedIndex } from '../types'; diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/edit_index_pattern.js b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/edit_index_pattern.js index 6d302ac5a74f3..594430ca01f4c 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/edit_index_pattern.js +++ b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/edit_index_pattern.js @@ -29,7 +29,6 @@ import { uiModules } from 'ui/modules'; import template from './edit_index_pattern.html'; import { fieldWildcardMatcher } from '../../../../../../../../plugins/kibana_utils/public'; import { subscribeWithScope } from '../../../../../../../../plugins/kibana_legacy/public'; -import { setup as managementSetup } from '../../../../../../management/public/legacy'; import React from 'react'; import { render, unmountComponentAtNode } from 'react-dom'; import { SourceFiltersTable } from './source_filters_table'; @@ -239,14 +238,12 @@ uiModules $scope.editSectionsProvider = Private(IndicesEditSectionsProvider); $scope.kbnUrl = Private(KbnUrlProvider); $scope.indexPattern = $route.current.locals.indexPattern; - $scope.indexPatternListProvider = managementSetup.indexPattern.list; - $scope.indexPattern.tags = managementSetup.indexPattern.list.getIndexPatternTags( + $scope.indexPatternListProvider = npStart.plugins.indexPatternManagement.list; + $scope.indexPattern.tags = npStart.plugins.indexPatternManagement.list.getIndexPatternTags( $scope.indexPattern, $scope.indexPattern.id === config.get('defaultIndex') ); - $scope.getFieldInfo = managementSetup.indexPattern.list.getFieldInfo.bind( - managementSetup.indexPattern.list - ); + $scope.getFieldInfo = npStart.plugins.indexPatternManagement.list.getFieldInfo; docTitle.change($scope.indexPattern.title); const otherPatterns = _.filter($route.current.locals.indexPatterns, pattern => { @@ -257,7 +254,7 @@ uiModules $scope.editSections = $scope.editSectionsProvider( $scope.indexPattern, $scope.fieldFilter, - managementSetup.indexPattern.list + npStart.plugins.indexPatternManagement.list ); $scope.refreshFilters(); $scope.fields = $scope.indexPattern.getNonScriptedFields(); @@ -363,7 +360,7 @@ uiModules $scope.editSections = $scope.editSectionsProvider( $scope.indexPattern, $scope.fieldFilter, - managementSetup.indexPattern.list + npStart.plugins.indexPatternManagement.list ); if ($scope.fieldFilter === undefined) { diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/index.js b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/index.js index 310797a7f3a0c..a8376c0e84bf9 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/index.js +++ b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/index.js @@ -18,7 +18,6 @@ */ import { management } from 'ui/management'; -import { setup as managementSetup } from '../../../../../management/public/legacy'; import './create_index_pattern_wizard'; import './edit_index_pattern'; import uiRoutes from 'ui/routes'; @@ -111,7 +110,7 @@ uiModules transclude: true, template: indexTemplate, link: async function($scope) { - const indexPatternCreationOptions = await managementSetup.indexPattern.creation.getIndexPatternCreationOptions( + const indexPatternCreationOptions = await npStart.plugins.indexPatternManagement.creation.getIndexPatternCreationOptions( url => { $scope.$evalAsync(() => kbnUrl.change(url)); } @@ -124,7 +123,7 @@ uiModules const id = pattern.id; const title = pattern.get('title'); const isDefault = $scope.defaultIndex === id; - const tags = managementSetup.indexPattern.list.getIndexPatternTags( + const tags = npStart.plugins.indexPatternManagement.list.getIndexPatternTags( pattern, isDefault ); diff --git a/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/__jest__/objects_table.test.js b/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/__jest__/objects_table.test.js index a5e34f8955fe3..7b9c17640a0f3 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/__jest__/objects_table.test.js +++ b/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/__jest__/objects_table.test.js @@ -19,7 +19,7 @@ import React from 'react'; import { shallowWithI18nProvider } from 'test_utils/enzyme_helpers'; -import { mockManagementPlugin } from '../../../../../../../../management/public/np_ready/mocks'; +import { mockManagementPlugin } from '../../../../../../../../../../plugins/index_pattern_management/public/mocks'; import { Query } from '@elastic/eui'; import { ObjectsTable, POSSIBLE_TYPES } from '../objects_table'; @@ -30,7 +30,7 @@ import { extractExportDetails } from '../../../lib/extract_export_details'; jest.mock('ui/kfetch', () => ({ kfetch: jest.fn() })); -jest.mock('../../../../../../../../management/public/legacy', () => ({ +jest.mock('../../../../../../../../../../plugins/index_pattern_management/public', () => ({ setup: mockManagementPlugin.createSetupContract(), start: mockManagementPlugin.createStartContract(), })); diff --git a/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/flyout/__jest__/flyout.test.js b/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/flyout/__jest__/flyout.test.js index 97c0d5b89d657..5d14c4609b918 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/flyout/__jest__/flyout.test.js +++ b/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/flyout/__jest__/flyout.test.js @@ -19,7 +19,7 @@ import React from 'react'; import { shallowWithI18nProvider } from 'test_utils/enzyme_helpers'; -import { mockManagementPlugin } from '../../../../../../../../../../management/public/np_ready/mocks'; +import { mockManagementPlugin } from '../../../../../../../../../../../../plugins/index_pattern_management/public/mocks'; import { Flyout } from '../flyout'; jest.mock('ui/kfetch', () => ({ kfetch: jest.fn() })); @@ -48,7 +48,7 @@ jest.mock('../../../../../lib/resolve_saved_objects', () => ({ saveObjects: jest.fn(), })); -jest.mock('../../../../../../../../../../management/public/legacy', () => ({ +jest.mock('../../../../../../../../../../../../plugins/index_pattern_management/public', () => ({ setup: mockManagementPlugin.createSetupContract(), start: mockManagementPlugin.createStartContract(), })); diff --git a/src/legacy/core_plugins/management/index.ts b/src/legacy/core_plugins/management/index.ts deleted file mode 100644 index 4962c948f842f..0000000000000 --- a/src/legacy/core_plugins/management/index.ts +++ /dev/null @@ -1,37 +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 { resolve } from 'path'; -import { Legacy } from '../../../../kibana'; - -// eslint-disable-next-line import/no-default-export -export default function ManagementPlugin(kibana: any) { - const config: Legacy.PluginSpecOptions = { - id: 'stack-management', - publicDir: resolve(__dirname, 'public'), - config: (Joi: any) => { - return Joi.object({ - enabled: Joi.boolean().default(true), - }).default(); - }, - init: (server: Legacy.Server) => ({}), - }; - - return new kibana.Plugin(config); -} diff --git a/src/legacy/core_plugins/management/package.json b/src/legacy/core_plugins/management/package.json deleted file mode 100644 index 77d33a7bce3b6..0000000000000 --- a/src/legacy/core_plugins/management/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "management", - "version": "kibana" -} - \ No newline at end of file diff --git a/src/legacy/core_plugins/management/public/index.ts b/src/legacy/core_plugins/management/public/index.ts deleted file mode 100644 index bc3737524e125..0000000000000 --- a/src/legacy/core_plugins/management/public/index.ts +++ /dev/null @@ -1,38 +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. - */ - -/** - * Static np-ready code, re-exported here so consumers can import from - * `src/legacy/core_plugins/management/public` - * - * @public - */ - -export { - ManagementSetup, - ManagementStart, - plugin, - IndexPatternCreationConfig, - IndexPatternListConfig, -} from './np_ready'; - -export { - processImportResponse, - ProcessedImportResponse, -} from '../../kibana/public/management/sections/objects/lib/process_import_response'; diff --git a/src/legacy/core_plugins/management/public/legacy.ts b/src/legacy/core_plugins/management/public/legacy.ts deleted file mode 100644 index 96d2c74398a0e..0000000000000 --- a/src/legacy/core_plugins/management/public/legacy.ts +++ /dev/null @@ -1,45 +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. - */ - -/** - * New Platform Shim - * - * In this file, we import any legacy dependencies we have, and shim them into - * our plugin by manually constructing the values that the new platform will - * eventually be passing to the `setup/start` method of our plugin definition. - * - * The idea is that our `plugin.ts` can stay "pure" and not contain any legacy - * world code. Then when it comes time to migrate to the new platform, we can - * simply delete this shim file. - * - * We are also calling `setup/start` here and exporting our public contract so that - * other legacy plugins are able to import from '../core_plugins/management/legacy' - * and receive the response value of the `setup/start` contract, mimicking the - * data that will eventually be injected by the new platform. - */ - -import { PluginInitializerContext } from 'src/core/public'; -import { npSetup, npStart } from 'ui/new_platform'; - -import { plugin } from '.'; - -const pluginInstance = plugin({} as PluginInitializerContext); - -export const setup = pluginInstance.setup(npSetup.core, { home: npSetup.plugins.home }); -export const start = pluginInstance.start(npStart.core, {}); diff --git a/src/legacy/ui/public/new_platform/new_platform.karma_mock.js b/src/legacy/ui/public/new_platform/new_platform.karma_mock.js index f70ef069dd134..0779d6472671c 100644 --- a/src/legacy/ui/public/new_platform/new_platform.karma_mock.js +++ b/src/legacy/ui/public/new_platform/new_platform.karma_mock.js @@ -290,6 +290,10 @@ export const npSetup = { }), }, }, + indexPatternManagement: { + list: { addListConfig: sinon.fake() }, + creation: { addCreationConfig: sinon.fake() }, + }, discover: { docViews: { addDocView: sinon.fake(), @@ -325,6 +329,17 @@ export const npStart = { }), }, }, + indexPatternManagement: { + list: { + getType: sinon.fake(), + getIndexPatternCreationOptions: sinon.fake(), + }, + creation: { + getIndexPatternTags: sinon.fake(), + getFieldInfo: sinon.fake(), + areScriptedFieldsEnabled: sinon.fake(), + }, + }, embeddable: { getEmbeddableFactory: sinon.fake(), getEmbeddableFactories: sinon.fake(), diff --git a/src/legacy/ui/public/new_platform/new_platform.ts b/src/legacy/ui/public/new_platform/new_platform.ts index b4b5099081759..cdd7e1a994912 100644 --- a/src/legacy/ui/public/new_platform/new_platform.ts +++ b/src/legacy/ui/public/new_platform/new_platform.ts @@ -47,6 +47,10 @@ import { AdvancedSettingsStart, } from '../../../../plugins/advanced_settings/public'; import { ManagementSetup, ManagementStart } from '../../../../plugins/management/public'; +import { + IndexPatternManagementSetup, + IndexPatternManagementStart, +} from '../../../../plugins/index_pattern_management/public'; import { BfetchPublicSetup, BfetchPublicStart } from '../../../../plugins/bfetch/public'; import { UsageCollectionSetup } from '../../../../plugins/usage_collection/public'; import { TelemetryPluginSetup, TelemetryPluginStart } from '../../../../plugins/telemetry/public'; @@ -86,6 +90,7 @@ export interface PluginsSetup { visualizations: VisualizationsSetup; telemetry?: TelemetryPluginSetup; savedObjectsManagement: SavedObjectsManagementPluginSetup; + indexPatternManagement: IndexPatternManagementSetup; } export interface PluginsStart { @@ -107,6 +112,7 @@ export interface PluginsStart { telemetry?: TelemetryPluginStart; dashboard: DashboardStart; savedObjectsManagement: SavedObjectsManagementPluginStart; + indexPatternManagement: IndexPatternManagementStart; } export const npSetup = { diff --git a/src/plugins/index_pattern_management/kibana.json b/src/plugins/index_pattern_management/kibana.json new file mode 100644 index 0000000000000..d5397a11184aa --- /dev/null +++ b/src/plugins/index_pattern_management/kibana.json @@ -0,0 +1,7 @@ +{ + "id": "indexPatternManagement", + "version": "kibana", + "server": false, + "ui": true, + "requiredPlugins": [] +} diff --git a/src/legacy/core_plugins/management/public/np_ready/index.ts b/src/plugins/index_pattern_management/public/index.ts similarity index 83% rename from src/legacy/core_plugins/management/public/np_ready/index.ts rename to src/plugins/index_pattern_management/public/index.ts index bae0f1d3e23cd..da482c0c51f0a 100644 --- a/src/legacy/core_plugins/management/public/np_ready/index.ts +++ b/src/plugins/index_pattern_management/public/index.ts @@ -29,14 +29,11 @@ * either types, or static code. */ import { PluginInitializerContext } from 'src/core/public'; -import { ManagementPlugin } from './plugin'; -export { ManagementSetup, ManagementStart } from './plugin'; +import { IndexPatternManagementPlugin } from './plugin'; +export { IndexPatternManagementSetup, IndexPatternManagementStart } from './plugin'; export function plugin(initializerContext: PluginInitializerContext) { - return new ManagementPlugin(initializerContext); + return new IndexPatternManagementPlugin(initializerContext); } -export { - IndexPatternCreationConfig, - IndexPatternListConfig, -} from './services/index_pattern_management'; +export { IndexPatternCreationConfig, IndexPatternListConfig } from './service'; diff --git a/src/legacy/core_plugins/management/public/np_ready/mocks.ts b/src/plugins/index_pattern_management/public/mocks.ts similarity index 57% rename from src/legacy/core_plugins/management/public/np_ready/mocks.ts rename to src/plugins/index_pattern_management/public/mocks.ts index ae0be98de63f3..bc97f46c302e3 100644 --- a/src/legacy/core_plugins/management/public/np_ready/mocks.ts +++ b/src/plugins/index_pattern_management/public/mocks.ts @@ -18,42 +18,38 @@ */ import { PluginInitializerContext } from 'src/core/public'; -import { coreMock } from '../../../../../core/public/mocks'; +import { coreMock } from '../../../core/public/mocks'; import { - ManagementSetup, - ManagementStart, - ManagementPlugin, - ManagementPluginSetupDependencies, + IndexPatternManagementSetup, + IndexPatternManagementStart, + IndexPatternManagementPlugin, } from './plugin'; -const createSetupContract = (): ManagementSetup => ({ - indexPattern: { - creation: { - add: jest.fn(), - getType: jest.fn(), - getIndexPatternCreationOptions: jest.fn(), - } as any, - list: { - add: jest.fn(), - getIndexPatternTags: jest.fn(), - getFieldInfo: jest.fn(), - areScriptedFieldsEnabled: jest.fn(), - } as any, - }, +const createSetupContract = (): IndexPatternManagementSetup => ({ + creation: { + addCreationConfig: jest.fn(), + } as any, + list: { + addListConfig: jest.fn(), + } as any, }); -const createStartContract = (): ManagementStart => ({}); +const createStartContract = (): IndexPatternManagementStart => ({ + creation: { + getType: jest.fn(), + getIndexPatternCreationOptions: jest.fn(), + } as any, + list: { + getIndexPatternTags: jest.fn(), + getFieldInfo: jest.fn(), + areScriptedFieldsEnabled: jest.fn(), + } as any, +}); const createInstance = async () => { - const plugin = new ManagementPlugin({} as PluginInitializerContext); + const plugin = new IndexPatternManagementPlugin({} as PluginInitializerContext); - const setup = plugin.setup(coreMock.createSetup(), ({ - home: { - featureCatalogue: { - register: jest.fn(), - }, - }, - } as unknown) as ManagementPluginSetupDependencies); + const setup = plugin.setup(coreMock.createSetup()); const doStart = () => plugin.start(coreMock.createStart(), {}); return { diff --git a/src/legacy/core_plugins/management/public/np_ready/plugin.ts b/src/plugins/index_pattern_management/public/plugin.ts similarity index 60% rename from src/legacy/core_plugins/management/public/np_ready/plugin.ts rename to src/plugins/index_pattern_management/public/plugin.ts index 2a8ef10c817cc..93bb0ead1df4a 100644 --- a/src/legacy/core_plugins/management/public/np_ready/plugin.ts +++ b/src/plugins/index_pattern_management/public/plugin.ts @@ -17,43 +17,40 @@ * under the License. */ import { PluginInitializerContext, CoreSetup, CoreStart, Plugin } from 'src/core/public'; -import { HomePublicPluginSetup } from 'src/plugins/home/public'; -import { IndexPatternManagementService, IndexPatternManagementSetup } from './services'; +import { + IndexPatternManagementService, + IndexPatternManagementServiceSetup, + IndexPatternManagementServiceStart, +} from './service'; -export interface ManagementPluginSetupDependencies { - home: HomePublicPluginSetup; -} +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface IndexPatternManagementSetupDependencies {} // eslint-disable-next-line @typescript-eslint/no-empty-interface -interface ManagementPluginStartDependencies {} +export interface IndexPatternManagementStartDependencies {} -export interface ManagementSetup { - indexPattern: IndexPatternManagementSetup; -} +export type IndexPatternManagementSetup = IndexPatternManagementServiceSetup; -// eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface ManagementStart {} +export type IndexPatternManagementStart = IndexPatternManagementServiceStart; -export class ManagementPlugin +export class IndexPatternManagementPlugin implements Plugin< - ManagementSetup, - ManagementStart, - ManagementPluginSetupDependencies, - ManagementPluginStartDependencies + IndexPatternManagementSetup, + IndexPatternManagementStart, + IndexPatternManagementSetupDependencies, + IndexPatternManagementStartDependencies > { private readonly indexPattern = new IndexPatternManagementService(); constructor(initializerContext: PluginInitializerContext) {} - public setup(core: CoreSetup, { home }: ManagementPluginSetupDependencies) { - return { - indexPattern: this.indexPattern.setup({ httpClient: core.http, home }), - }; + public setup(core: CoreSetup) { + return this.indexPattern.setup({ httpClient: core.http }); } - public start(core: CoreStart, plugins: ManagementPluginStartDependencies) { - return {}; + public start(core: CoreStart, plugins: IndexPatternManagementStartDependencies) { + return this.indexPattern.start(); } public stop() { diff --git a/src/legacy/core_plugins/management/public/np_ready/services/index_pattern_management/creation/config.ts b/src/plugins/index_pattern_management/public/service/creation/config.ts similarity index 88% rename from src/legacy/core_plugins/management/public/np_ready/services/index_pattern_management/creation/config.ts rename to src/plugins/index_pattern_management/public/service/creation/config.ts index 5714fa3338962..29ab0ebfc3d5f 100644 --- a/src/legacy/core_plugins/management/public/np_ready/services/index_pattern_management/creation/config.ts +++ b/src/plugins/index_pattern_management/public/service/creation/config.ts @@ -18,20 +18,20 @@ */ import { i18n } from '@kbn/i18n'; -import { MatchedIndex } from '../../../../../../kibana/public/management/sections/index_patterns/create_index_pattern_wizard/types'; +import { MatchedIndex } from '../../../../../legacy/core_plugins/kibana/public/management/sections/index_patterns/create_index_pattern_wizard/types'; const indexPatternTypeName = i18n.translate( - 'management.editIndexPattern.createIndex.defaultTypeName', + 'indexPatternManagement.editIndexPattern.createIndex.defaultTypeName', { defaultMessage: 'index pattern' } ); const indexPatternButtonText = i18n.translate( - 'management.editIndexPattern.createIndex.defaultButtonText', + 'indexPatternManagement.editIndexPattern.createIndex.defaultButtonText', { defaultMessage: 'Standard index pattern' } ); const indexPatternButtonDescription = i18n.translate( - 'management.editIndexPattern.createIndex.defaultButtonDescription', + 'indexPatternManagement.editIndexPattern.createIndex.defaultButtonDescription', { defaultMessage: 'Perform full aggregations against any data' } ); diff --git a/src/legacy/core_plugins/management/public/np_ready/services/index_pattern_management/creation/index.ts b/src/plugins/index_pattern_management/public/service/creation/index.ts similarity index 100% rename from src/legacy/core_plugins/management/public/np_ready/services/index_pattern_management/creation/index.ts rename to src/plugins/index_pattern_management/public/service/creation/index.ts diff --git a/src/legacy/core_plugins/management/public/np_ready/services/index_pattern_management/creation/manager.ts b/src/plugins/index_pattern_management/public/service/creation/manager.ts similarity index 79% rename from src/legacy/core_plugins/management/public/np_ready/services/index_pattern_management/creation/manager.ts rename to src/plugins/index_pattern_management/public/service/creation/manager.ts index e7fa13409ab04..32b3e7ee7a133 100644 --- a/src/legacy/core_plugins/management/public/np_ready/services/index_pattern_management/creation/manager.ts +++ b/src/plugins/index_pattern_management/public/service/creation/manager.ts @@ -17,23 +17,25 @@ * under the License. */ -import { HttpSetup } from '../../../../../../../../core/public'; +import { HttpSetup } from '../../../../../core/public'; import { IndexPatternCreationConfig, UrlHandler, IndexPatternCreationOption } from './config'; export class IndexPatternCreationManager { private configs: IndexPatternCreationConfig[]; - constructor(private readonly httpClient: HttpSetup) { + constructor() { this.configs = []; } - public add(Config: typeof IndexPatternCreationConfig) { - const config = new Config({ httpClient: this.httpClient }); + public addCreationConfig = (httpClient: HttpSetup) => ( + Config: typeof IndexPatternCreationConfig + ) => { + const config = new Config({ httpClient }); if (this.configs.findIndex(c => c.key === config.key) !== -1) { throw new Error(`${config.key} exists in IndexPatternCreationManager.`); } this.configs.push(config); - } + }; public getType(key: string | undefined): IndexPatternCreationConfig | null { if (key) { @@ -58,4 +60,13 @@ export class IndexPatternCreationManager { ); return options; } + + setup = (httpClient: HttpSetup) => ({ + addCreationConfig: this.addCreationConfig(httpClient).bind(this), + }); + + start = () => ({ + getType: this.getType.bind(this), + getIndexPatternCreationOptions: this.getIndexPatternCreationOptions.bind(this), + }); } diff --git a/src/legacy/core_plugins/management/public/np_ready/services/index_pattern_management/index.ts b/src/plugins/index_pattern_management/public/service/index.ts similarity index 100% rename from src/legacy/core_plugins/management/public/np_ready/services/index_pattern_management/index.ts rename to src/plugins/index_pattern_management/public/service/index.ts diff --git a/src/legacy/core_plugins/management/public/np_ready/services/index_pattern_management/index_pattern_management_service.ts b/src/plugins/index_pattern_management/public/service/index_pattern_management_service.ts similarity index 51% rename from src/legacy/core_plugins/management/public/np_ready/services/index_pattern_management/index_pattern_management_service.ts rename to src/plugins/index_pattern_management/public/service/index_pattern_management_service.ts index 2b6f008dd928a..4780fa00ed468 100644 --- a/src/legacy/core_plugins/management/public/np_ready/services/index_pattern_management/index_pattern_management_service.ts +++ b/src/plugins/index_pattern_management/public/service/index_pattern_management_service.ts @@ -17,18 +17,12 @@ * under the License. */ -import { i18n } from '@kbn/i18n'; -import { - FeatureCatalogueCategory, - HomePublicPluginSetup, -} from '../../../../../../../plugins/home/public'; -import { HttpSetup } from '../../../../../../../core/public'; +import { HttpSetup } from '../../../../core/public'; import { IndexPatternCreationManager, IndexPatternCreationConfig } from './creation'; import { IndexPatternListManager, IndexPatternListConfig } from './list'; interface SetupDependencies { httpClient: HttpSetup; - home: HomePublicPluginSetup; } /** @@ -37,31 +31,29 @@ interface SetupDependencies { * @internal */ export class IndexPatternManagementService { - public setup({ httpClient, home }: SetupDependencies) { - const creation = new IndexPatternCreationManager(httpClient); - const list = new IndexPatternListManager(); + indexPatternCreationManager: IndexPatternCreationManager; + indexPatternListConfig: IndexPatternListManager; - creation.add(IndexPatternCreationConfig); - list.add(IndexPatternListConfig); + constructor() { + this.indexPatternCreationManager = new IndexPatternCreationManager(); + this.indexPatternListConfig = new IndexPatternListManager(); + } + + public setup({ httpClient }: SetupDependencies) { + const creationManagerSetup = this.indexPatternCreationManager.setup(httpClient); + creationManagerSetup.addCreationConfig(IndexPatternCreationConfig); + this.indexPatternListConfig.setup().addListConfig(IndexPatternListConfig); - home.featureCatalogue.register({ - id: 'index_patterns', - title: i18n.translate('management.indexPatternHeader', { - defaultMessage: 'Index Patterns', - }), - description: i18n.translate('management.indexPatternLabel', { - defaultMessage: - 'Manage the index patterns that help retrieve your data from Elasticsearch.', - }), - icon: 'indexPatternApp', - path: '/app/kibana#/management/kibana/index_patterns', - showOnHomePage: true, - category: FeatureCatalogueCategory.ADMIN, - }); + return { + creation: creationManagerSetup, + list: this.indexPatternListConfig.setup(), + }; + } + public start() { return { - creation, - list, + creation: this.indexPatternCreationManager.start(), + list: this.indexPatternListConfig.start(), }; } @@ -71,4 +63,5 @@ export class IndexPatternManagementService { } /** @internal */ -export type IndexPatternManagementSetup = ReturnType; +export type IndexPatternManagementServiceSetup = ReturnType; +export type IndexPatternManagementServiceStart = ReturnType; diff --git a/src/legacy/core_plugins/management/public/np_ready/services/index_pattern_management/list/config.ts b/src/plugins/index_pattern_management/public/service/list/config.ts similarity index 87% rename from src/legacy/core_plugins/management/public/np_ready/services/index_pattern_management/list/config.ts rename to src/plugins/index_pattern_management/public/service/list/config.ts index dd4d77a681171..87c246e8913e5 100644 --- a/src/legacy/core_plugins/management/public/np_ready/services/index_pattern_management/list/config.ts +++ b/src/plugins/index_pattern_management/public/service/list/config.ts @@ -33,9 +33,12 @@ export class IndexPatternListConfig { ? [ { key: 'default', - name: i18n.translate('management.editIndexPattern.list.defaultIndexPatternListName', { - defaultMessage: 'Default', - }), + name: i18n.translate( + 'indexPatternManagement.editIndexPattern.list.defaultIndexPatternListName', + { + defaultMessage: 'Default', + } + ), }, ] : []; diff --git a/src/legacy/core_plugins/management/public/np_ready/services/index_pattern_management/list/index.ts b/src/plugins/index_pattern_management/public/service/list/index.ts similarity index 100% rename from src/legacy/core_plugins/management/public/np_ready/services/index_pattern_management/list/index.ts rename to src/plugins/index_pattern_management/public/service/list/index.ts diff --git a/src/legacy/core_plugins/management/public/np_ready/services/index_pattern_management/list/manager.ts b/src/plugins/index_pattern_management/public/service/list/manager.ts similarity index 75% rename from src/legacy/core_plugins/management/public/np_ready/services/index_pattern_management/list/manager.ts rename to src/plugins/index_pattern_management/public/service/list/manager.ts index 73ca33ae914a9..3a2910a222cd7 100644 --- a/src/legacy/core_plugins/management/public/np_ready/services/index_pattern_management/list/manager.ts +++ b/src/plugins/index_pattern_management/public/service/list/manager.ts @@ -27,7 +27,7 @@ export class IndexPatternListManager { this.configs = []; } - public add(Config: typeof IndexPatternListConfig) { + private addListConfig(Config: typeof IndexPatternListConfig) { const config = new Config(); if (this.configs.findIndex(c => c.key === config.key) !== -1) { throw new Error(`${config.key} exists in IndexPatternListManager.`); @@ -35,7 +35,7 @@ export class IndexPatternListManager { this.configs.push(config); } - public getIndexPatternTags(indexPattern: IIndexPattern, isDefault: boolean) { + private getIndexPatternTags(indexPattern: IIndexPattern, isDefault: boolean) { return this.configs.reduce((tags: IndexPatternTag[], config) => { return config.getIndexPatternTags ? tags.concat(config.getIndexPatternTags(indexPattern, isDefault)) @@ -43,15 +43,25 @@ export class IndexPatternListManager { }, []); } - public getFieldInfo(indexPattern: IIndexPattern, field: IFieldType): string[] { + private getFieldInfo(indexPattern: IIndexPattern, field: IFieldType): string[] { return this.configs.reduce((info: string[], config) => { return config.getFieldInfo ? info.concat(config.getFieldInfo(indexPattern, field)) : info; }, []); } - public areScriptedFieldsEnabled(indexPattern: IIndexPattern): boolean { + private areScriptedFieldsEnabled(indexPattern: IIndexPattern): boolean { return this.configs.every(config => { return config.areScriptedFieldsEnabled ? config.areScriptedFieldsEnabled(indexPattern) : true; }); } + + setup = () => ({ + addListConfig: this.addListConfig.bind(this), + }); + + start = () => ({ + getIndexPatternTags: this.getIndexPatternTags.bind(this), + getFieldInfo: this.getFieldInfo.bind(this), + areScriptedFieldsEnabled: this.areScriptedFieldsEnabled.bind(this), + }); } diff --git a/x-pack/legacy/plugins/rollup/kibana.json b/x-pack/legacy/plugins/rollup/kibana.json index 3781d59d8c0f3..3df8bd7c187d5 100644 --- a/x-pack/legacy/plugins/rollup/kibana.json +++ b/x-pack/legacy/plugins/rollup/kibana.json @@ -4,7 +4,8 @@ "requiredPlugins": [ "home", "index_management", - "metrics" + "metrics", + "indexPatternManagement" ], "optionalPlugins": [ "usageCollection" diff --git a/x-pack/legacy/plugins/rollup/public/index_pattern_creation/rollup_index_pattern_creation_config.js b/x-pack/legacy/plugins/rollup/public/index_pattern_creation/rollup_index_pattern_creation_config.js index f0eb21a219442..f4de2a3098127 100644 --- a/x-pack/legacy/plugins/rollup/public/index_pattern_creation/rollup_index_pattern_creation_config.js +++ b/x-pack/legacy/plugins/rollup/public/index_pattern_creation/rollup_index_pattern_creation_config.js @@ -8,7 +8,7 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import { RollupPrompt } from './components/rollup_prompt'; -import { IndexPatternCreationConfig } from '../../../../../../src/legacy/core_plugins/management/public'; +import { IndexPatternCreationConfig } from '../../../../../../src/plugins/index_pattern_management/public'; const rollupIndexPatternTypeName = i18n.translate( 'xpack.rollupJobs.editRollupIndexPattern.createIndex.defaultTypeName', diff --git a/x-pack/legacy/plugins/rollup/public/index_pattern_list/rollup_index_pattern_list_config.js b/x-pack/legacy/plugins/rollup/public/index_pattern_list/rollup_index_pattern_list_config.js index fbf2612b83aa8..809a76d1868b2 100644 --- a/x-pack/legacy/plugins/rollup/public/index_pattern_list/rollup_index_pattern_list_config.js +++ b/x-pack/legacy/plugins/rollup/public/index_pattern_list/rollup_index_pattern_list_config.js @@ -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 { IndexPatternListConfig } from '../../../../../../src/legacy/core_plugins/management/public'; +import { IndexPatternListConfig } from '../../../../../../src/plugins/index_pattern_management/public'; function isRollup(indexPattern) { return ( diff --git a/x-pack/legacy/plugins/rollup/public/legacy.ts b/x-pack/legacy/plugins/rollup/public/legacy.ts index ec530e63408f4..83945110c2c76 100644 --- a/x-pack/legacy/plugins/rollup/public/legacy.ts +++ b/x-pack/legacy/plugins/rollup/public/legacy.ts @@ -6,14 +6,8 @@ import { npSetup, npStart } from 'ui/new_platform'; import { RollupPlugin } from './plugin'; -import { setup as management } from '../../../../../src/legacy/core_plugins/management/public/legacy'; const plugin = new RollupPlugin(); -export const setup = plugin.setup(npSetup.core, { - ...npSetup.plugins, - __LEGACY: { - managementLegacy: management, - }, -}); +export const setup = plugin.setup(npSetup.core, npSetup.plugins); export const start = plugin.start(npStart.core, npStart.plugins); diff --git a/x-pack/legacy/plugins/rollup/public/plugin.ts b/x-pack/legacy/plugins/rollup/public/plugin.ts index c58975419e20f..5782e88c3448b 100644 --- a/x-pack/legacy/plugins/rollup/public/plugin.ts +++ b/x-pack/legacy/plugins/rollup/public/plugin.ts @@ -7,7 +7,6 @@ import { i18n } from '@kbn/i18n'; import { CoreSetup, CoreStart, Plugin } from 'kibana/public'; import { PluginsStart } from './legacy_imports'; -import { ManagementSetup as ManagementSetupLegacy } from '../../../../../src/legacy/core_plugins/management/public/np_ready'; import { rollupBadgeExtension, rollupToggleExtension } from './extend_index_management'; // @ts-ignore import { RollupIndexPatternCreationConfig } from './index_pattern_creation/rollup_index_pattern_creation_config'; @@ -26,6 +25,7 @@ import { import { CRUD_APP_BASE_PATH } from './crud_app/constants'; import { ManagementSetup } from '../../../../../src/plugins/management/public'; import { IndexMgmtSetup } from '../../../../plugins/index_management/public'; +import { IndexPatternManagementSetup } from '../../../../../src/plugins/index_pattern_management/public'; import { search } from '../../../../../src/plugins/data/public'; // @ts-ignore import { setEsBaseAndXPackBase, setHttp } from './crud_app/services'; @@ -33,23 +33,16 @@ import { setNotifications, setFatalErrors } from './kibana_services'; import { renderApp } from './application'; export interface RollupPluginSetupDependencies { - __LEGACY: { - managementLegacy: ManagementSetupLegacy; - }; home?: HomePublicPluginSetup; management: ManagementSetup; indexManagement?: IndexMgmtSetup; + indexPatternManagement: IndexPatternManagementSetup; } export class RollupPlugin implements Plugin { setup( core: CoreSetup, - { - __LEGACY: { managementLegacy }, - home, - management, - indexManagement, - }: RollupPluginSetupDependencies + { home, management, indexManagement, indexPatternManagement }: RollupPluginSetupDependencies ) { setFatalErrors(core.fatalErrors); @@ -61,8 +54,8 @@ export class RollupPlugin implements Plugin { const isRollupIndexPatternsEnabled = core.uiSettings.get(CONFIG_ROLLUPS); if (isRollupIndexPatternsEnabled) { - managementLegacy.indexPattern.creation.add(RollupIndexPatternCreationConfig); - managementLegacy.indexPattern.list.add(RollupIndexPatternListConfig); + indexPatternManagement.creation.addCreationConfig(RollupIndexPatternCreationConfig); + indexPatternManagement.list.addListConfig(RollupIndexPatternListConfig); } if (home) { diff --git a/x-pack/plugins/spaces/public/copy_saved_objects_to_space/components/copy_to_space_flyout.test.tsx b/x-pack/plugins/spaces/public/copy_saved_objects_to_space/components/copy_to_space_flyout.test.tsx index 7809b511adda4..99b4e184c071a 100644 --- a/x-pack/plugins/spaces/public/copy_saved_objects_to_space/components/copy_to_space_flyout.test.tsx +++ b/x-pack/plugins/spaces/public/copy_saved_objects_to_space/components/copy_to_space_flyout.test.tsx @@ -6,7 +6,6 @@ import React from 'react'; import Boom from 'boom'; import { mountWithIntl, nextTick } from 'test_utils/enzyme_helpers'; -import { mockManagementPlugin } from '../../../../../../src/legacy/core_plugins/management/public/np_ready/mocks'; import { CopySavedObjectsToSpaceFlyout } from './copy_to_space_flyout'; import { CopyToSpaceForm } from './copy_to_space_form'; import { EuiLoadingSpinner, EuiEmptyPrompt } from '@elastic/eui'; @@ -19,11 +18,6 @@ import { spacesManagerMock } from '../../spaces_manager/mocks'; import { SpacesManager } from '../../spaces_manager'; import { ToastsApi } from 'src/core/public'; -jest.mock('../../../../../../src/legacy/core_plugins/management/public/legacy', () => ({ - setup: mockManagementPlugin.createSetupContract(), - start: mockManagementPlugin.createStartContract(), -})); - interface SetupOpts { mockSpaces?: Space[]; returnBeforeSpacesLoad?: boolean; diff --git a/x-pack/plugins/spaces/public/copy_saved_objects_to_space/components/copy_to_space_flyout.tsx b/x-pack/plugins/spaces/public/copy_saved_objects_to_space/components/copy_to_space_flyout.tsx index 4d92505c4aebb..fee41fc7e36d3 100644 --- a/x-pack/plugins/spaces/public/copy_saved_objects_to_space/components/copy_to_space_flyout.tsx +++ b/x-pack/plugins/spaces/public/copy_saved_objects_to_space/components/copy_to_space_flyout.tsx @@ -25,7 +25,7 @@ import { ToastsStart } from 'src/core/public'; import { ProcessedImportResponse, processImportResponse, -} from '../../../../../../src/legacy/core_plugins/management/public'; +} from '../../../../../../src/legacy/core_plugins/kibana/public'; import { SavedObjectsManagementRecord } from '../../../../../../src/plugins/saved_objects_management/public'; import { Space } from '../../../common/model/space'; import { SpacesManager } from '../../spaces_manager'; diff --git a/x-pack/plugins/spaces/public/copy_saved_objects_to_space/components/copy_to_space_flyout_footer.tsx b/x-pack/plugins/spaces/public/copy_saved_objects_to_space/components/copy_to_space_flyout_footer.tsx index b22cec0af5ea8..4f6ff55dbfbb2 100644 --- a/x-pack/plugins/spaces/public/copy_saved_objects_to_space/components/copy_to_space_flyout_footer.tsx +++ b/x-pack/plugins/spaces/public/copy_saved_objects_to_space/components/copy_to_space_flyout_footer.tsx @@ -8,7 +8,7 @@ import React, { Fragment } from 'react'; import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiStat, EuiHorizontalRule } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; -import { ProcessedImportResponse } from '../../../../../../src/legacy/core_plugins/management/public'; +import { ProcessedImportResponse } from '../../../../../../src/legacy/core_plugins/kibana/public'; import { ImportRetry } from '../types'; interface Props { diff --git a/x-pack/plugins/spaces/public/copy_saved_objects_to_space/components/processing_copy_to_space.tsx b/x-pack/plugins/spaces/public/copy_saved_objects_to_space/components/processing_copy_to_space.tsx index 96cbac4b48065..ea74fc92b95ea 100644 --- a/x-pack/plugins/spaces/public/copy_saved_objects_to_space/components/processing_copy_to_space.tsx +++ b/x-pack/plugins/spaces/public/copy_saved_objects_to_space/components/processing_copy_to_space.tsx @@ -13,7 +13,7 @@ import { EuiHorizontalRule, } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -import { ProcessedImportResponse } from '../../../../../../src/legacy/core_plugins/management/public'; +import { ProcessedImportResponse } from '../../../../../../src/legacy/core_plugins/kibana/public'; import { SavedObjectsManagementRecord } from '../../../../../../src/plugins/saved_objects_management/public'; import { Space } from '../../../common/model/space'; import { CopyOptions, ImportRetry } from '../types'; diff --git a/x-pack/plugins/spaces/public/copy_saved_objects_to_space/summarize_copy_result.test.ts b/x-pack/plugins/spaces/public/copy_saved_objects_to_space/summarize_copy_result.test.ts index fb2616619c644..65a0cabfeb716 100644 --- a/x-pack/plugins/spaces/public/copy_saved_objects_to_space/summarize_copy_result.test.ts +++ b/x-pack/plugins/spaces/public/copy_saved_objects_to_space/summarize_copy_result.test.ts @@ -5,7 +5,7 @@ */ import { summarizeCopyResult } from './summarize_copy_result'; -import { ProcessedImportResponse } from 'src/legacy/core_plugins/management/public'; +import { ProcessedImportResponse } from 'src/legacy/core_plugins/kibana/public'; const createSavedObjectsManagementRecord = () => ({ type: 'dashboard', diff --git a/x-pack/plugins/spaces/public/copy_saved_objects_to_space/summarize_copy_result.ts b/x-pack/plugins/spaces/public/copy_saved_objects_to_space/summarize_copy_result.ts index 96e642b0f45d8..44c9e9993bf10 100644 --- a/x-pack/plugins/spaces/public/copy_saved_objects_to_space/summarize_copy_result.ts +++ b/x-pack/plugins/spaces/public/copy_saved_objects_to_space/summarize_copy_result.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { ProcessedImportResponse } from 'src/legacy/core_plugins/management/public'; +import { ProcessedImportResponse } from 'src/legacy/core_plugins/kibana/public'; import { SavedObjectsManagementRecord } from 'src/plugins/saved_objects_management/public'; export interface SummarizedSavedObjectResult { diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index d07026c0883b8..00ac5b77d00f3 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -2523,12 +2523,10 @@ "management.breadcrumb": "管理", "management.connectDataDisplayName": "データに接続", "management.displayName": "管理", - "management.editIndexPattern.createIndex.defaultButtonDescription": "すべてのデータに完全集約を実行", - "management.editIndexPattern.createIndex.defaultButtonText": "標準インデックスパターン", - "management.editIndexPattern.createIndex.defaultTypeName": "インデックスパターン", - "management.editIndexPattern.list.defaultIndexPatternListName": "デフォルト", - "management.indexPatternHeader": "インデックスパターン", - "management.indexPatternLabel": "Elasticsearch からのデータの取得に役立つインデックスパターンを管理します。", + "indexPatternManagement.editIndexPattern.createIndex.defaultButtonDescription": "すべてのデータに完全集約を実行", + "indexPatternManagement.editIndexPattern.createIndex.defaultButtonText": "標準インデックスパターン", + "indexPatternManagement.editIndexPattern.createIndex.defaultTypeName": "インデックスパターン", + "indexPatternManagement.editIndexPattern.list.defaultIndexPatternListName": "デフォルト", "management.nav.label": "管理", "management.nav.menu": "管理メニュー", "management.stackManagement.managementDescription": "Elastic Stack の管理を行うセンターコンソールです。", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 7e64ff6301faf..f6d84431bef7f 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -2524,12 +2524,10 @@ "management.breadcrumb": "管理", "management.connectDataDisplayName": "连接数据", "management.displayName": "管理", - "management.editIndexPattern.createIndex.defaultButtonDescription": "对任何数据执行完全聚合", - "management.editIndexPattern.createIndex.defaultButtonText": "标准索引模式", - "management.editIndexPattern.createIndex.defaultTypeName": "索引模式", - "management.editIndexPattern.list.defaultIndexPatternListName": "默认值", - "management.indexPatternHeader": "索引模式", - "management.indexPatternLabel": "管理帮助从 Elasticsearch 检索数据的索引模式。", + "indexPatternManagement.editIndexPattern.createIndex.defaultButtonDescription": "对任何数据执行完全聚合", + "indexPatternManagement.editIndexPattern.createIndex.defaultButtonText": "标准索引模式", + "indexPatternManagement.editIndexPattern.createIndex.defaultTypeName": "索引模式", + "indexPatternManagement.editIndexPattern.list.defaultIndexPatternListName": "默认值", "management.nav.label": "管理", "management.nav.menu": "管理菜单", "management.stackManagement.managementDescription": "您用于管理 Elastic Stack 的中心控制台。", From fdb4a37a6016c8afce52203ecccbe03e6fc4064e Mon Sep 17 00:00:00 2001 From: Lee Drengenberg Date: Wed, 8 Apr 2020 20:33:21 +0000 Subject: [PATCH 31/40] restore empty_kibana after saved objects test (#62951) --- test/functional/apps/management/_mgmt_import_saved_objects.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/functional/apps/management/_mgmt_import_saved_objects.js b/test/functional/apps/management/_mgmt_import_saved_objects.js index 53b7e7062ee2d..2f9d9f9bfb178 100644 --- a/test/functional/apps/management/_mgmt_import_saved_objects.js +++ b/test/functional/apps/management/_mgmt_import_saved_objects.js @@ -35,6 +35,7 @@ export default function({ getService, getPageObjects }) { afterEach(async function() { await esArchiver.unload('discover'); + await esArchiver.load('empty_kibana'); }); it('should import saved objects mgmt', async function() { From 86a25876601053604d08ad4884db796066b819b2 Mon Sep 17 00:00:00 2001 From: Jen Huang Date: Wed, 8 Apr 2020 13:33:51 -0700 Subject: [PATCH 32/40] [Ingest] Data source configuration validation UI (#61180) * Initial pass at datasource configuration validation * Show error icon and red text at input and stream levels * Add tests, fix bugs in validation method * Fix typings --- .../components/datasource_input_config.tsx | 63 ++- .../components/datasource_input_panel.tsx | 50 +- .../datasource_input_stream_config.tsx | 55 +- .../components/datasource_input_var_field.tsx | 28 +- .../components/index.ts | 1 + .../create_datasource_page/index.tsx | 16 +- .../create_datasource_page/services/index.ts | 7 + .../services/validate_datasource.test.ts | 504 ++++++++++++++++++ .../services/validate_datasource.ts | 232 ++++++++ .../step_configure_datasource.tsx | 169 ++++-- .../ingest_manager/services/index.ts | 2 + .../ingest_manager/types/index.ts | 3 + 12 files changed, 1038 insertions(+), 92 deletions(-) create mode 100644 x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/services/validate_datasource.test.ts create mode 100644 x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/services/validate_datasource.ts diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/components/datasource_input_config.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/components/datasource_input_config.tsx index 356739af1ff9a..0e8763cb2d4c0 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/components/datasource_input_config.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/components/datasource_input_config.tsx @@ -6,26 +6,38 @@ import React, { useState, Fragment } from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; import { - EuiFlexGrid, EuiFlexGroup, EuiFlexItem, EuiText, + EuiTextColor, EuiSpacer, EuiButtonEmpty, EuiTitle, + EuiIconTip, } from '@elastic/eui'; import { DatasourceInput, RegistryVarsEntry } from '../../../../types'; -import { isAdvancedVar } from '../services'; +import { isAdvancedVar, DatasourceConfigValidationResults, validationHasErrors } from '../services'; import { DatasourceInputVarField } from './datasource_input_var_field'; export const DatasourceInputConfig: React.FunctionComponent<{ packageInputVars?: RegistryVarsEntry[]; datasourceInput: DatasourceInput; updateDatasourceInput: (updatedInput: Partial) => void; -}> = ({ packageInputVars, datasourceInput, updateDatasourceInput }) => { + inputVarsValidationResults: DatasourceConfigValidationResults; + forceShowErrors?: boolean; +}> = ({ + packageInputVars, + datasourceInput, + updateDatasourceInput, + inputVarsValidationResults, + forceShowErrors, +}) => { // Showing advanced options toggle state const [isShowingAdvanced, setIsShowingAdvanced] = useState(false); + // Errors state + const hasErrors = forceShowErrors && validationHasErrors(inputVarsValidationResults); + const requiredVars: RegistryVarsEntry[] = []; const advancedVars: RegistryVarsEntry[] = []; @@ -40,15 +52,36 @@ export const DatasourceInputConfig: React.FunctionComponent<{ } return ( - - + + -

- -

+ + +

+ + + +

+
+ {hasErrors ? ( + + + } + position="right" + type="alert" + iconProps={{ color: 'danger' }} + /> + + ) : null} +
@@ -60,7 +93,7 @@ export const DatasourceInputConfig: React.FunctionComponent<{

- + {requiredVars.map(varDef => { const { name: varName, type: varType } = varDef; @@ -81,6 +114,8 @@ export const DatasourceInputConfig: React.FunctionComponent<{ }, }); }} + errors={inputVarsValidationResults.config![varName]} + forceShowErrors={forceShowErrors} /> ); @@ -123,6 +158,8 @@ export const DatasourceInputConfig: React.FunctionComponent<{ }, }); }} + errors={inputVarsValidationResults.config![varName]} + forceShowErrors={forceShowErrors} /> ); @@ -132,6 +169,6 @@ export const DatasourceInputConfig: React.FunctionComponent<{ ) : null}
-
+ ); }; diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/components/datasource_input_panel.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/components/datasource_input_panel.tsx index 74b08f48df12d..6b0c68ccb7d3f 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/components/datasource_input_panel.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/components/datasource_input_panel.tsx @@ -17,8 +17,10 @@ import { EuiButtonIcon, EuiHorizontalRule, EuiSpacer, + EuiIconTip, } from '@elastic/eui'; import { DatasourceInput, DatasourceInputStream, RegistryInput } from '../../../../types'; +import { DatasourceInputValidationResults, validationHasErrors } from '../services'; import { DatasourceInputConfig } from './datasource_input_config'; import { DatasourceInputStreamConfig } from './datasource_input_stream_config'; @@ -32,10 +34,21 @@ export const DatasourceInputPanel: React.FunctionComponent<{ packageInput: RegistryInput; datasourceInput: DatasourceInput; updateDatasourceInput: (updatedInput: Partial) => void; -}> = ({ packageInput, datasourceInput, updateDatasourceInput }) => { + inputValidationResults: DatasourceInputValidationResults; + forceShowErrors?: boolean; +}> = ({ + packageInput, + datasourceInput, + updateDatasourceInput, + inputValidationResults, + forceShowErrors, +}) => { // Showing streams toggle state const [isShowingStreams, setIsShowingStreams] = useState(false); + // Errors state + const hasErrors = forceShowErrors && validationHasErrors(inputValidationResults); + return ( {/* Header / input-level toggle */} @@ -43,9 +56,32 @@ export const DatasourceInputPanel: React.FunctionComponent<{ -

{packageInput.title || packageInput.type}

-
+ + + +

+ + {packageInput.title || packageInput.type} + +

+
+
+ {hasErrors ? ( + + + } + position="right" + type="alert" + iconProps={{ color: 'danger' }} + /> + + ) : null} +
} checked={datasourceInput.enabled} onChange={e => { @@ -122,6 +158,8 @@ export const DatasourceInputPanel: React.FunctionComponent<{ packageInputVars={packageInput.vars} datasourceInput={datasourceInput} updateDatasourceInput={updateDatasourceInput} + inputVarsValidationResults={{ config: inputValidationResults.config }} + forceShowErrors={forceShowErrors} /> @@ -165,6 +203,10 @@ export const DatasourceInputPanel: React.FunctionComponent<{ updateDatasourceInput(updatedInput); }} + inputStreamValidationResults={ + inputValidationResults.streams![datasourceInputStream.id] + } + forceShowErrors={forceShowErrors} /> diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/components/datasource_input_stream_config.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/components/datasource_input_stream_config.tsx index 3bf5b2bb4c0f0..43e8f5a2c060d 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/components/datasource_input_stream_config.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/components/datasource_input_stream_config.tsx @@ -7,26 +7,38 @@ import React, { useState, Fragment } from 'react'; import ReactMarkdown from 'react-markdown'; import { FormattedMessage } from '@kbn/i18n/react'; import { - EuiFlexGrid, EuiFlexGroup, EuiFlexItem, EuiSwitch, EuiText, EuiSpacer, EuiButtonEmpty, + EuiTextColor, + EuiIconTip, } from '@elastic/eui'; import { DatasourceInputStream, RegistryStream, RegistryVarsEntry } from '../../../../types'; -import { isAdvancedVar } from '../services'; +import { isAdvancedVar, DatasourceConfigValidationResults, validationHasErrors } from '../services'; import { DatasourceInputVarField } from './datasource_input_var_field'; export const DatasourceInputStreamConfig: React.FunctionComponent<{ packageInputStream: RegistryStream; datasourceInputStream: DatasourceInputStream; updateDatasourceInputStream: (updatedStream: Partial) => void; -}> = ({ packageInputStream, datasourceInputStream, updateDatasourceInputStream }) => { + inputStreamValidationResults: DatasourceConfigValidationResults; + forceShowErrors?: boolean; +}> = ({ + packageInputStream, + datasourceInputStream, + updateDatasourceInputStream, + inputStreamValidationResults, + forceShowErrors, +}) => { // Showing advanced options toggle state const [isShowingAdvanced, setIsShowingAdvanced] = useState(false); + // Errors state + const hasErrors = forceShowErrors && validationHasErrors(inputStreamValidationResults); + const requiredVars: RegistryVarsEntry[] = []; const advancedVars: RegistryVarsEntry[] = []; @@ -41,10 +53,33 @@ export const DatasourceInputStreamConfig: React.FunctionComponent<{ } return ( - - + + + + + {packageInputStream.title || packageInputStream.dataset} + + + {hasErrors ? ( + + + } + position="right" + type="alert" + iconProps={{ color: 'danger' }} + /> + + ) : null} + + } checked={datasourceInputStream.enabled} onChange={e => { const enabled = e.target.checked; @@ -62,7 +97,7 @@ export const DatasourceInputStreamConfig: React.FunctionComponent<{ ) : null} - + {requiredVars.map(varDef => { const { name: varName, type: varType } = varDef; @@ -83,6 +118,8 @@ export const DatasourceInputStreamConfig: React.FunctionComponent<{ }, }); }} + errors={inputStreamValidationResults.config![varName]} + forceShowErrors={forceShowErrors} /> ); @@ -125,6 +162,8 @@ export const DatasourceInputStreamConfig: React.FunctionComponent<{ }, }); }} + errors={inputStreamValidationResults.config![varName]} + forceShowErrors={forceShowErrors} /> ); @@ -134,6 +173,6 @@ export const DatasourceInputStreamConfig: React.FunctionComponent<{ ) : null} - + ); }; diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/components/datasource_input_var_field.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/components/datasource_input_var_field.tsx index bcb99eed88ac0..846a807f9240d 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/components/datasource_input_var_field.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/components/datasource_input_var_field.tsx @@ -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 React from 'react'; +import React, { useState } from 'react'; import ReactMarkdown from 'react-markdown'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiFormRow, EuiFieldText, EuiComboBox, EuiText, EuiCodeEditor } from '@elastic/eui'; @@ -16,12 +16,20 @@ export const DatasourceInputVarField: React.FunctionComponent<{ varDef: RegistryVarsEntry; value: any; onChange: (newValue: any) => void; -}> = ({ varDef, value, onChange }) => { + errors?: string[] | null; + forceShowErrors?: boolean; +}> = ({ varDef, value, onChange, errors: varErrors, forceShowErrors }) => { + const [isDirty, setIsDirty] = useState(false); + const { multi, required, type, title, name, description } = varDef; + const isInvalid = (isDirty || forceShowErrors) && !!varErrors; + const errors = isInvalid ? varErrors : null; + const renderField = () => { - if (varDef.multi) { + if (multi) { return ( ({ label: val }))} onCreateOption={(newVal: any) => { onChange([...value, newVal]); @@ -29,10 +37,11 @@ export const DatasourceInputVarField: React.FunctionComponent<{ onChange={(newVals: any[]) => { onChange(newVals.map(val => val.label)); }} + onBlur={() => setIsDirty(true)} /> ); } - if (varDef.type === 'yaml') { + if (type === 'yaml') { return ( onChange(newVal)} + onBlur={() => setIsDirty(true)} /> ); } return ( onChange(e.target.value)} + onBlur={() => setIsDirty(true)} /> ); }; return ( ) : null } - helpText={} + helpText={} > {renderField()} diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/components/index.ts b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/components/index.ts index e5f18e1449d1b..3bfca75668911 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/components/index.ts +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/components/index.ts @@ -5,3 +5,4 @@ */ export { CreateDatasourcePageLayout } from './layout'; export { DatasourceInputPanel } from './datasource_input_panel'; +export { DatasourceInputVarField } from './datasource_input_var_field'; diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/index.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/index.tsx index 23d0f3317a667..7815ab9cd1d6e 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/index.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/index.tsx @@ -21,6 +21,7 @@ import { useLinks as useEPMLinks } from '../../epm/hooks'; import { CreateDatasourcePageLayout } from './components'; import { CreateDatasourceFrom, CreateDatasourceStep } from './types'; import { CREATE_DATASOURCE_STEP_PATHS } from './constants'; +import { DatasourceValidationResults, validateDatasource } from './services'; import { StepSelectPackage } from './step_select_package'; import { StepSelectConfig } from './step_select_config'; import { StepConfigureDatasource } from './step_configure_datasource'; @@ -51,6 +52,9 @@ export const CreateDatasourcePage: React.FunctionComponent = () => { inputs: [], }); + // Datasource validation state + const [validationResults, setValidationResults] = useState(); + // Update package info method const updatePackageInfo = (updatedPackageInfo: PackageInfo | undefined) => { if (updatedPackageInfo) { @@ -84,9 +88,18 @@ export const CreateDatasourcePage: React.FunctionComponent = () => { ...updatedFields, }; setDatasource(newDatasource); - // eslint-disable-next-line no-console console.debug('Datasource updated', newDatasource); + updateDatasourceValidation(newDatasource); + }; + + const updateDatasourceValidation = (newDatasource?: NewDatasource) => { + if (packageInfo) { + const newValidationResult = validateDatasource(newDatasource || datasource, packageInfo); + setValidationResults(newValidationResult); + // eslint-disable-next-line no-console + console.debug('Datasource validation results', newValidationResult); + } }; // Cancel url @@ -202,6 +215,7 @@ export const CreateDatasourcePage: React.FunctionComponent = () => { packageInfo={packageInfo} datasource={datasource} updateDatasource={updateDatasource} + validationResults={validationResults!} backLink={ {from === 'config' ? ( diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/services/index.ts b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/services/index.ts index 44e5bfa41cb9b..d99f0712db3c3 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/services/index.ts +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/services/index.ts @@ -4,3 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ export { isAdvancedVar } from './is_advanced_var'; +export { + DatasourceValidationResults, + DatasourceConfigValidationResults, + DatasourceInputValidationResults, + validateDatasource, + validationHasErrors, +} from './validate_datasource'; diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/services/validate_datasource.test.ts b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/services/validate_datasource.test.ts new file mode 100644 index 0000000000000..a45fabeb5ed6a --- /dev/null +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/services/validate_datasource.test.ts @@ -0,0 +1,504 @@ +/* + * 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 { + PackageInfo, + InstallationStatus, + NewDatasource, + RegistryDatasource, +} from '../../../../types'; +import { validateDatasource, validationHasErrors } from './validate_datasource'; + +describe('Ingest Manager - validateDatasource()', () => { + const mockPackage = ({ + name: 'mock-package', + title: 'Mock package', + version: '0.0.0', + description: 'description', + type: 'mock', + categories: [], + requirement: { kibana: { versions: '' }, elasticsearch: { versions: '' } }, + format_version: '', + download: '', + path: '', + assets: { + kibana: { + dashboard: [], + visualization: [], + search: [], + 'index-pattern': [], + }, + }, + status: InstallationStatus.notInstalled, + datasources: [ + { + name: 'datasource1', + title: 'Datasource 1', + description: 'test datasource', + inputs: [ + { + type: 'foo', + title: 'Foo', + vars: [ + { default: 'foo-input-var-value', name: 'foo-input-var-name', type: 'text' }, + { + default: 'foo-input2-var-value', + name: 'foo-input2-var-name', + required: true, + type: 'text', + }, + { name: 'foo-input3-var-name', type: 'text', required: true, multi: true }, + ], + streams: [ + { + dataset: 'foo', + input: 'foo', + title: 'Foo', + vars: [{ name: 'var-name', type: 'yaml' }], + }, + ], + }, + { + type: 'bar', + title: 'Bar', + vars: [ + { + default: ['value1', 'value2'], + name: 'bar-input-var-name', + type: 'text', + multi: true, + }, + { name: 'bar-input2-var-name', required: true, type: 'text' }, + ], + streams: [ + { + dataset: 'bar', + input: 'bar', + title: 'Bar', + vars: [{ name: 'var-name', type: 'yaml', required: true }], + }, + { + dataset: 'bar2', + input: 'bar2', + title: 'Bar 2', + vars: [{ default: 'bar2-var-value', name: 'var-name', type: 'text' }], + }, + ], + }, + { + type: 'with-no-config-or-streams', + title: 'With no config or streams', + streams: [], + }, + { + type: 'with-disabled-streams', + title: 'With disabled streams', + streams: [ + { + dataset: 'disabled', + input: 'disabled', + title: 'Disabled', + enabled: false, + vars: [{ multi: true, required: true, name: 'var-name', type: 'text' }], + }, + { dataset: 'disabled2', input: 'disabled2', title: 'Disabled 2', enabled: false }, + ], + }, + ], + }, + ], + } as unknown) as PackageInfo; + + const validDatasource: NewDatasource = { + name: 'datasource1-1', + config_id: 'test-config', + enabled: true, + output_id: 'test-output', + inputs: [ + { + type: 'foo', + enabled: true, + config: { + 'foo-input-var-name': { value: 'foo-input-var-value', type: 'text' }, + 'foo-input2-var-name': { value: 'foo-input2-var-value', type: 'text' }, + 'foo-input3-var-name': { value: ['test'], type: 'text' }, + }, + streams: [ + { + id: 'foo-foo', + dataset: 'foo', + enabled: true, + config: { 'var-name': { value: 'test_yaml: value', type: 'yaml' } }, + }, + ], + }, + { + type: 'bar', + enabled: true, + config: { + 'bar-input-var-name': { value: ['value1', 'value2'], type: 'text' }, + 'bar-input2-var-name': { value: 'test', type: 'text' }, + }, + streams: [ + { + id: 'bar-bar', + dataset: 'bar', + enabled: true, + config: { 'var-name': { value: 'test_yaml: value', type: 'yaml' } }, + }, + { + id: 'bar-bar2', + dataset: 'bar2', + enabled: true, + config: { 'var-name': { value: undefined, type: 'text' } }, + }, + ], + }, + { + type: 'with-no-config-or-streams', + enabled: true, + streams: [], + }, + { + type: 'with-disabled-streams', + enabled: true, + streams: [ + { + id: 'with-disabled-streams-disabled', + dataset: 'disabled', + enabled: false, + config: { 'var-name': { value: undefined, type: 'text' } }, + }, + { + id: 'with-disabled-streams-disabled2', + dataset: 'disabled2', + enabled: false, + }, + ], + }, + ], + }; + + const invalidDatasource: NewDatasource = { + ...validDatasource, + name: '', + inputs: [ + { + type: 'foo', + enabled: true, + config: { + 'foo-input-var-name': { value: undefined, type: 'text' }, + 'foo-input2-var-name': { value: '', type: 'text' }, + 'foo-input3-var-name': { value: [], type: 'text' }, + }, + streams: [ + { + id: 'foo-foo', + dataset: 'foo', + enabled: true, + config: { 'var-name': { value: 'invalidyaml: test\n foo bar:', type: 'yaml' } }, + }, + ], + }, + { + type: 'bar', + enabled: true, + config: { + 'bar-input-var-name': { value: 'invalid value for multi', type: 'text' }, + 'bar-input2-var-name': { value: undefined, type: 'text' }, + }, + streams: [ + { + id: 'bar-bar', + dataset: 'bar', + enabled: true, + config: { 'var-name': { value: ' \n\n', type: 'yaml' } }, + }, + { + id: 'bar-bar2', + dataset: 'bar2', + enabled: true, + config: { 'var-name': { value: undefined, type: 'text' } }, + }, + ], + }, + { + type: 'with-no-config-or-streams', + enabled: true, + streams: [], + }, + { + type: 'with-disabled-streams', + enabled: true, + streams: [ + { + id: 'with-disabled-streams-disabled', + dataset: 'disabled', + enabled: false, + config: { + 'var-name': { + value: 'invalid value but not checked due to not enabled', + type: 'text', + }, + }, + }, + { + id: 'with-disabled-streams-disabled2', + dataset: 'disabled2', + enabled: false, + }, + ], + }, + ], + }; + + const noErrorsValidationResults = { + name: null, + description: null, + inputs: { + foo: { + config: { + 'foo-input-var-name': null, + 'foo-input2-var-name': null, + 'foo-input3-var-name': null, + }, + streams: { 'foo-foo': { config: { 'var-name': null } } }, + }, + bar: { + config: { 'bar-input-var-name': null, 'bar-input2-var-name': null }, + streams: { + 'bar-bar': { config: { 'var-name': null } }, + 'bar-bar2': { config: { 'var-name': null } }, + }, + }, + 'with-disabled-streams': { + streams: { 'with-disabled-streams-disabled': { config: { 'var-name': null } } }, + }, + }, + }; + + it('returns no errors for valid datasource configuration', () => { + expect(validateDatasource(validDatasource, mockPackage)).toEqual(noErrorsValidationResults); + }); + + it('returns errors for invalid datasource configuration', () => { + expect(validateDatasource(invalidDatasource, mockPackage)).toEqual({ + name: ['Name is required'], + description: null, + inputs: { + foo: { + config: { + 'foo-input-var-name': null, + 'foo-input2-var-name': ['foo-input2-var-name is required'], + 'foo-input3-var-name': ['foo-input3-var-name is required'], + }, + streams: { 'foo-foo': { config: { 'var-name': ['Invalid YAML format'] } } }, + }, + bar: { + config: { + 'bar-input-var-name': ['Invalid format'], + 'bar-input2-var-name': ['bar-input2-var-name is required'], + }, + streams: { + 'bar-bar': { config: { 'var-name': ['var-name is required'] } }, + 'bar-bar2': { config: { 'var-name': null } }, + }, + }, + 'with-disabled-streams': { + streams: { 'with-disabled-streams-disabled': { config: { 'var-name': null } } }, + }, + }, + }); + }); + + it('returns no errors for disabled inputs', () => { + const disabledInputs = invalidDatasource.inputs.map(input => ({ ...input, enabled: false })); + expect(validateDatasource({ ...validDatasource, inputs: disabledInputs }, mockPackage)).toEqual( + noErrorsValidationResults + ); + }); + + it('returns only datasource and input-level errors for disabled streams', () => { + const inputsWithDisabledStreams = invalidDatasource.inputs.map(input => + input.streams + ? { + ...input, + streams: input.streams.map(stream => ({ ...stream, enabled: false })), + } + : input + ); + expect( + validateDatasource({ ...invalidDatasource, inputs: inputsWithDisabledStreams }, mockPackage) + ).toEqual({ + name: ['Name is required'], + description: null, + inputs: { + foo: { + config: { + 'foo-input-var-name': null, + 'foo-input2-var-name': ['foo-input2-var-name is required'], + 'foo-input3-var-name': ['foo-input3-var-name is required'], + }, + streams: { 'foo-foo': { config: { 'var-name': null } } }, + }, + bar: { + config: { + 'bar-input-var-name': ['Invalid format'], + 'bar-input2-var-name': ['bar-input2-var-name is required'], + }, + streams: { + 'bar-bar': { config: { 'var-name': null } }, + 'bar-bar2': { config: { 'var-name': null } }, + }, + }, + 'with-disabled-streams': { + streams: { 'with-disabled-streams-disabled': { config: { 'var-name': null } } }, + }, + }, + }); + }); + + it('returns no errors for packages with no datasources', () => { + expect( + validateDatasource(validDatasource, { + ...mockPackage, + datasources: undefined, + }) + ).toEqual({ + name: null, + description: null, + inputs: null, + }); + expect( + validateDatasource(validDatasource, { + ...mockPackage, + datasources: [], + }) + ).toEqual({ + name: null, + description: null, + inputs: null, + }); + }); + + it('returns no errors for packages with no inputs', () => { + expect( + validateDatasource(validDatasource, { + ...mockPackage, + datasources: [{} as RegistryDatasource], + }) + ).toEqual({ + name: null, + description: null, + inputs: null, + }); + expect( + validateDatasource(validDatasource, { + ...mockPackage, + datasources: [({ inputs: [] } as unknown) as RegistryDatasource], + }) + ).toEqual({ + name: null, + description: null, + inputs: null, + }); + }); +}); + +describe('Ingest Manager - validationHasErrors()', () => { + it('returns true for stream validation results with errors', () => { + expect( + validationHasErrors({ + config: { foo: ['foo error'], bar: null }, + }) + ).toBe(true); + }); + + it('returns false for stream validation results with no errors', () => { + expect( + validationHasErrors({ + config: { foo: null, bar: null }, + }) + ).toBe(false); + }); + + it('returns true for input validation results with errors', () => { + expect( + validationHasErrors({ + config: { foo: ['foo error'], bar: null }, + streams: { stream1: { config: { foo: null, bar: null } } }, + }) + ).toBe(true); + expect( + validationHasErrors({ + config: { foo: null, bar: null }, + streams: { stream1: { config: { foo: ['foo error'], bar: null } } }, + }) + ).toBe(true); + }); + + it('returns false for input validation results with no errors', () => { + expect( + validationHasErrors({ + config: { foo: null, bar: null }, + streams: { stream1: { config: { foo: null, bar: null } } }, + }) + ).toBe(false); + }); + + it('returns true for datasource validation results with errors', () => { + expect( + validationHasErrors({ + name: ['name error'], + description: null, + inputs: { + input1: { + config: { foo: null, bar: null }, + streams: { stream1: { config: { foo: null, bar: null } } }, + }, + }, + }) + ).toBe(true); + expect( + validationHasErrors({ + name: null, + description: null, + inputs: { + input1: { + config: { foo: ['foo error'], bar: null }, + streams: { stream1: { config: { foo: null, bar: null } } }, + }, + }, + }) + ).toBe(true); + expect( + validationHasErrors({ + name: null, + description: null, + inputs: { + input1: { + config: { foo: null, bar: null }, + streams: { stream1: { config: { foo: ['foo error'], bar: null } } }, + }, + }, + }) + ).toBe(true); + }); + + it('returns false for datasource validation results with no errors', () => { + expect( + validationHasErrors({ + name: null, + description: null, + inputs: { + input1: { + config: { foo: null, bar: null }, + streams: { stream1: { config: { foo: null, bar: null } } }, + }, + }, + }) + ).toBe(false); + }); +}); diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/services/validate_datasource.ts b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/services/validate_datasource.ts new file mode 100644 index 0000000000000..518e2bfc1af07 --- /dev/null +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/services/validate_datasource.ts @@ -0,0 +1,232 @@ +/* + * 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 { safeLoad } from 'js-yaml'; +import { getFlattenedObject } from '../../../../services'; +import { + NewDatasource, + DatasourceInput, + DatasourceInputStream, + DatasourceConfigRecordEntry, + PackageInfo, + RegistryInput, + RegistryVarsEntry, +} from '../../../../types'; + +type Errors = string[] | null; + +type ValidationEntry = Record; + +export interface DatasourceConfigValidationResults { + config?: ValidationEntry; +} + +export type DatasourceInputValidationResults = DatasourceConfigValidationResults & { + streams?: Record; +}; + +export interface DatasourceValidationResults { + name: Errors; + description: Errors; + inputs: Record | null; +} + +/* + * Returns validation information for a given datasource configuration and package info + * Note: this method assumes that `datasource` is correctly structured for the given package + */ +export const validateDatasource = ( + datasource: NewDatasource, + packageInfo: PackageInfo +): DatasourceValidationResults => { + const validationResults: DatasourceValidationResults = { + name: null, + description: null, + inputs: {}, + }; + + if (!datasource.name.trim()) { + validationResults.name = [ + i18n.translate('xpack.ingestManager.datasourceValidation.nameRequiredErrorMessage', { + defaultMessage: 'Name is required', + }), + ]; + } + + if ( + !packageInfo.datasources || + packageInfo.datasources.length === 0 || + !packageInfo.datasources[0] || + !packageInfo.datasources[0].inputs || + packageInfo.datasources[0].inputs.length === 0 + ) { + validationResults.inputs = null; + return validationResults; + } + + const registryInputsByType: Record< + string, + RegistryInput + > = packageInfo.datasources[0].inputs.reduce((inputs, registryInput) => { + inputs[registryInput.type] = registryInput; + return inputs; + }, {} as Record); + + // Validate each datasource input with either its own config fields or streams + datasource.inputs.forEach(input => { + if (!input.config && !input.streams) { + return; + } + + const inputValidationResults: DatasourceInputValidationResults = { + config: undefined, + streams: {}, + }; + + const inputVarsByName = (registryInputsByType[input.type].vars || []).reduce( + (vars, registryVar) => { + vars[registryVar.name] = registryVar; + return vars; + }, + {} as Record + ); + + // Validate input-level config fields + const inputConfigs = Object.entries(input.config || {}); + if (inputConfigs.length) { + inputValidationResults.config = inputConfigs.reduce((results, [name, configEntry]) => { + results[name] = input.enabled + ? validateDatasourceConfig(configEntry, inputVarsByName[name]) + : null; + return results; + }, {} as ValidationEntry); + } else { + delete inputValidationResults.config; + } + + // Validate each input stream with config fields + if (input.streams.length) { + input.streams.forEach(stream => { + if (!stream.config) { + return; + } + + const streamValidationResults: DatasourceConfigValidationResults = { + config: undefined, + }; + + const streamVarsByName = ( + ( + registryInputsByType[input.type].streams.find( + registryStream => registryStream.dataset === stream.dataset + ) || {} + ).vars || [] + ).reduce((vars, registryVar) => { + vars[registryVar.name] = registryVar; + return vars; + }, {} as Record); + + // Validate stream-level config fields + streamValidationResults.config = Object.entries(stream.config).reduce( + (results, [name, configEntry]) => { + results[name] = + input.enabled && stream.enabled + ? validateDatasourceConfig(configEntry, streamVarsByName[name]) + : null; + return results; + }, + {} as ValidationEntry + ); + + inputValidationResults.streams![stream.id] = streamValidationResults; + }); + } else { + delete inputValidationResults.streams; + } + + if (inputValidationResults.config || inputValidationResults.streams) { + validationResults.inputs![input.type] = inputValidationResults; + } + }); + + if (Object.entries(validationResults.inputs!).length === 0) { + validationResults.inputs = null; + } + return validationResults; +}; + +const validateDatasourceConfig = ( + configEntry: DatasourceConfigRecordEntry, + varDef: RegistryVarsEntry +): string[] | null => { + const errors = []; + const { value } = configEntry; + let parsedValue: any = value; + + if (typeof value === 'string') { + parsedValue = value.trim(); + } + + if (varDef.required) { + if (parsedValue === undefined || (typeof parsedValue === 'string' && !parsedValue)) { + errors.push( + i18n.translate('xpack.ingestManager.datasourceValidation.requiredErrorMessage', { + defaultMessage: '{fieldName} is required', + values: { + fieldName: varDef.title || varDef.name, + }, + }) + ); + } + } + + if (varDef.type === 'yaml') { + try { + parsedValue = safeLoad(value); + } catch (e) { + errors.push( + i18n.translate('xpack.ingestManager.datasourceValidation.invalidYamlFormatErrorMessage', { + defaultMessage: 'Invalid YAML format', + }) + ); + } + } + + if (varDef.multi) { + if (parsedValue && !Array.isArray(parsedValue)) { + errors.push( + i18n.translate('xpack.ingestManager.datasourceValidation.invalidArrayErrorMessage', { + defaultMessage: 'Invalid format', + }) + ); + } + if ( + varDef.required && + (!parsedValue || (Array.isArray(parsedValue) && parsedValue.length === 0)) + ) { + errors.push( + i18n.translate('xpack.ingestManager.datasourceValidation.requiredErrorMessage', { + defaultMessage: '{fieldName} is required', + values: { + fieldName: varDef.title || varDef.name, + }, + }) + ); + } + } + + return errors.length ? errors : null; +}; + +export const validationHasErrors = ( + validationResults: + | DatasourceValidationResults + | DatasourceInputValidationResults + | DatasourceConfigValidationResults +) => { + const flattenedValidation = getFlattenedObject(validationResults); + return !!Object.entries(flattenedValidation).find(([, value]) => !!value); +}; diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/step_configure_datasource.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/step_configure_datasource.tsx index b45beef4a8b5e..105d6c66a5704 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/step_configure_datasource.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/step_configure_datasource.tsx @@ -9,17 +9,16 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { EuiSteps, EuiPanel, - EuiFlexGrid, EuiFlexGroup, EuiFlexItem, EuiFormRow, - EuiFieldText, EuiButtonEmpty, EuiSpacer, EuiEmptyPrompt, EuiText, EuiButton, EuiComboBox, + EuiCallOut, } from '@elastic/eui'; import { AgentConfig, @@ -28,21 +27,37 @@ import { NewDatasource, DatasourceInput, } from '../../../types'; +import { Loading } from '../../../components'; import { packageToConfigDatasourceInputs } from '../../../services'; -import { DatasourceInputPanel } from './components'; +import { DatasourceValidationResults, validationHasErrors } from './services'; +import { DatasourceInputPanel, DatasourceInputVarField } from './components'; export const StepConfigureDatasource: React.FunctionComponent<{ agentConfig: AgentConfig; packageInfo: PackageInfo; datasource: NewDatasource; updateDatasource: (fields: Partial) => void; + validationResults: DatasourceValidationResults; backLink: JSX.Element; cancelUrl: string; onNext: () => void; -}> = ({ agentConfig, packageInfo, datasource, updateDatasource, backLink, cancelUrl, onNext }) => { +}> = ({ + agentConfig, + packageInfo, + datasource, + updateDatasource, + validationResults, + backLink, + cancelUrl, + onNext, +}) => { // Form show/hide states const [isShowingAdvancedDefine, setIsShowingAdvancedDefine] = useState(false); + // Form submit state + const [submitAttempted, setSubmitAttempted] = useState(false); + const hasErrors = validationResults ? validationHasErrors(validationResults) : false; + // Update datasource's package and config info useEffect(() => { const dsPackage = datasource.package; @@ -81,56 +96,56 @@ export const StepConfigureDatasource: React.FunctionComponent<{ }, [datasource.package, datasource.config_id, agentConfig, packageInfo, updateDatasource]); // Step A, define datasource - const DefineDatasource = ( + const renderDefineDatasource = () => ( - - - - } - > - - updateDatasource({ - name: e.target.value, - }) - } - /> - + + + { + updateDatasource({ + name: newValue, + }); + }} + errors={validationResults!.name} + forceShowErrors={submitAttempted} + /> - - - } - labelAppend={ - - - - } - > - - updateDatasource({ - description: e.target.value, - }) - } - /> - + + { + updateDatasource({ + description: newValue, + }); + }} + errors={validationResults!.description} + forceShowErrors={submitAttempted} + /> - + - - + + - + + ) : null} @@ -182,7 +198,7 @@ export const StepConfigureDatasource: React.FunctionComponent<{ // Step B, configure inputs (and their streams) // Assume packages only export one datasource for now - const ConfigureInputs = + const renderConfigureInputs = () => packageInfo.datasources && packageInfo.datasources[0] && packageInfo.datasources[0].inputs && @@ -208,6 +224,8 @@ export const StepConfigureDatasource: React.FunctionComponent<{ inputs: newInputs, }); }} + inputValidationResults={validationResults!.inputs![datasourceInput.type]} + forceShowErrors={submitAttempted} /> ) : null; @@ -232,7 +250,7 @@ export const StepConfigureDatasource: React.FunctionComponent<{ ); - return ( + return validationResults ? ( @@ -251,7 +269,7 @@ export const StepConfigureDatasource: React.FunctionComponent<{ defaultMessage: 'Define your datasource', } ), - children: DefineDatasource, + children: renderDefineDatasource(), }, { title: i18n.translate( @@ -260,13 +278,34 @@ export const StepConfigureDatasource: React.FunctionComponent<{ defaultMessage: 'Choose the data you want to collect', } ), - children: ConfigureInputs, + children: renderConfigureInputs(), }, ]} /> + {hasErrors && submitAttempted ? ( + + +

+ +

+
+ +
+ ) : null} @@ -278,7 +317,17 @@ export const StepConfigureDatasource: React.FunctionComponent<{
- onNext()}> + { + setSubmitAttempted(true); + if (!hasErrors) { + onNext(); + } + }} + > + ) : ( + ); }; diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/services/index.ts b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/services/index.ts index 0aa08602e4d4d..5ebd1300baf65 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/services/index.ts +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/services/index.ts @@ -4,6 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ +export { getFlattenedObject } from '../../../../../../../src/core/utils'; + export { agentConfigRouteService, datasourceRouteService, diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/types/index.ts b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/types/index.ts index 333a9b049fa85..32615278b67d7 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/types/index.ts +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/types/index.ts @@ -16,6 +16,7 @@ export { NewDatasource, DatasourceInput, DatasourceInputStream, + DatasourceConfigRecordEntry, // API schemas - Agent Config GetAgentConfigsResponse, GetAgentConfigsResponseItem, @@ -56,6 +57,7 @@ export { RegistryVarsEntry, RegistryInput, RegistryStream, + RegistryDatasource, PackageList, PackageListItem, PackagesGroupedByStatus, @@ -70,4 +72,5 @@ export { DeletePackageResponse, DetailViewPanelName, InstallStatus, + InstallationStatus, } from '../../../../common'; From 578e443bdd79ea6436289ee39703816fe7419ebd Mon Sep 17 00:00:00 2001 From: Dmitry Lemeshko Date: Thu, 9 Apr 2020 00:08:21 +0300 Subject: [PATCH 33/40] FTR: add chromium-based Edge browser support (#61684) * bump dependency, add edge support in ftr services * add config files * fix browser version for msedge * use npm ms-chromium-edge-driver * download edge driver aside from session creation * move dependency to dev * update dist/index file * bump edge-driver version * change type to msedge to match w3c spec * fix discover tests for Edge * Revert "fix discover tests for Edge" This reverts commit 87e7fdd256433ef1ad392147d6bd63b925552b37. * bump driver version up Co-authored-by: Elastic Machine --- package.json | 5 +- packages/kbn-pm/dist/index.js | 1105 +++-------------- .../lib/config/schema.ts | 2 +- test/functional/config.edge.js | 34 + test/functional/services/browser.ts | 4 +- .../web_element_wrapper.ts | 9 +- test/functional/services/remote/browsers.ts | 1 + test/functional/services/remote/remote.ts | 17 +- test/functional/services/remote/webdriver.ts | 50 +- x-pack/test/functional/config.edge.js | 21 + yarn.lock | 320 ++++- 11 files changed, 556 insertions(+), 1012 deletions(-) create mode 100644 test/functional/config.edge.js create mode 100644 x-pack/test/functional/config.edge.js diff --git a/package.json b/package.json index 4c5db5321c282..bd0fec3a5c116 100644 --- a/package.json +++ b/package.json @@ -376,7 +376,7 @@ "@types/recompose": "^0.30.6", "@types/redux-actions": "^2.6.1", "@types/request": "^2.48.2", - "@types/selenium-webdriver": "^4.0.5", + "@types/selenium-webdriver": "4.0.9", "@types/semver": "^5.5.0", "@types/sinon": "^7.0.13", "@types/strip-ansi": "^3.0.0", @@ -462,6 +462,7 @@ "load-grunt-config": "^3.0.1", "mocha": "^7.1.1", "mock-http-server": "1.3.0", + "ms-chromium-edge-driver": "^0.2.0", "multistream": "^2.1.1", "murmurhash3js": "3.0.1", "mutation-observer": "^1.0.3", @@ -480,7 +481,7 @@ "react-textarea-autosize": "^7.1.2", "regenerate": "^1.4.0", "sass-lint": "^1.12.1", - "selenium-webdriver": "^4.0.0-alpha.5", + "selenium-webdriver": "^4.0.0-alpha.7", "simple-git": "1.116.0", "simplebar-react": "^2.1.0", "sinon": "^7.4.2", diff --git a/packages/kbn-pm/dist/index.js b/packages/kbn-pm/dist/index.js index 0cc1ad6326671..7a858deff41d3 100644 --- a/packages/kbn-pm/dist/index.js +++ b/packages/kbn-pm/dist/index.js @@ -79260,7 +79260,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _build_production_projects__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(705); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "buildProductionProjects", function() { return _build_production_projects__WEBPACK_IMPORTED_MODULE_0__["buildProductionProjects"]; }); -/* harmony import */ var _prepare_project_dependencies__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(928); +/* harmony import */ var _prepare_project_dependencies__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(923); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "prepareExternalProjectDependencies", function() { return _prepare_project_dependencies__WEBPACK_IMPORTED_MODULE_1__["prepareExternalProjectDependencies"]; }); /* @@ -79445,9 +79445,9 @@ const pAll = __webpack_require__(707); const arrify = __webpack_require__(709); const globby = __webpack_require__(710); const isGlob = __webpack_require__(604); -const cpFile = __webpack_require__(913); -const junk = __webpack_require__(925); -const CpyError = __webpack_require__(926); +const cpFile = __webpack_require__(908); +const junk = __webpack_require__(920); +const CpyError = __webpack_require__(921); const defaultOptions = { ignoreJunk: true @@ -79697,8 +79697,8 @@ const fs = __webpack_require__(23); const arrayUnion = __webpack_require__(711); const glob = __webpack_require__(713); const fastGlob = __webpack_require__(718); -const dirGlob = __webpack_require__(906); -const gitignore = __webpack_require__(909); +const dirGlob = __webpack_require__(901); +const gitignore = __webpack_require__(904); const DEFAULT_FILTER = () => false; @@ -81531,11 +81531,11 @@ module.exports.generateTasks = pkg.generateTasks; Object.defineProperty(exports, "__esModule", { value: true }); var optionsManager = __webpack_require__(720); var taskManager = __webpack_require__(721); -var reader_async_1 = __webpack_require__(877); -var reader_stream_1 = __webpack_require__(901); -var reader_sync_1 = __webpack_require__(902); -var arrayUtils = __webpack_require__(904); -var streamUtils = __webpack_require__(905); +var reader_async_1 = __webpack_require__(872); +var reader_stream_1 = __webpack_require__(896); +var reader_sync_1 = __webpack_require__(897); +var arrayUtils = __webpack_require__(899); +var streamUtils = __webpack_require__(900); /** * Synchronous API. */ @@ -82175,9 +82175,9 @@ var extend = __webpack_require__(838); */ var compilers = __webpack_require__(841); -var parsers = __webpack_require__(873); -var cache = __webpack_require__(874); -var utils = __webpack_require__(875); +var parsers = __webpack_require__(868); +var cache = __webpack_require__(869); +var utils = __webpack_require__(870); var MAX_LENGTH = 1024 * 64; /** @@ -100710,9 +100710,9 @@ var toRegex = __webpack_require__(729); */ var compilers = __webpack_require__(858); -var parsers = __webpack_require__(869); -var Extglob = __webpack_require__(872); -var utils = __webpack_require__(871); +var parsers = __webpack_require__(864); +var Extglob = __webpack_require__(867); +var utils = __webpack_require__(866); var MAX_LENGTH = 1024 * 64; /** @@ -101222,7 +101222,7 @@ var parsers = __webpack_require__(862); * Module dependencies */ -var debug = __webpack_require__(864)('expand-brackets'); +var debug = __webpack_require__(801)('expand-brackets'); var extend = __webpack_require__(738); var Snapdragon = __webpack_require__(768); var toRegex = __webpack_require__(729); @@ -101816,839 +101816,12 @@ exports.createRegex = function(pattern, include) { /* 864 */ /***/ (function(module, exports, __webpack_require__) { -/** - * Detect Electron renderer process, which is node, but we should - * treat as a browser. - */ - -if (typeof process !== 'undefined' && process.type === 'renderer') { - module.exports = __webpack_require__(865); -} else { - module.exports = __webpack_require__(868); -} - - -/***/ }), -/* 865 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * This is the web browser implementation of `debug()`. - * - * Expose `debug()` as the module. - */ - -exports = module.exports = __webpack_require__(866); -exports.log = log; -exports.formatArgs = formatArgs; -exports.save = save; -exports.load = load; -exports.useColors = useColors; -exports.storage = 'undefined' != typeof chrome - && 'undefined' != typeof chrome.storage - ? chrome.storage.local - : localstorage(); - -/** - * Colors. - */ - -exports.colors = [ - 'lightseagreen', - 'forestgreen', - 'goldenrod', - 'dodgerblue', - 'darkorchid', - 'crimson' -]; - -/** - * Currently only WebKit-based Web Inspectors, Firefox >= v31, - * and the Firebug extension (any Firefox version) are known - * to support "%c" CSS customizations. - * - * TODO: add a `localStorage` variable to explicitly enable/disable colors - */ - -function useColors() { - // NB: In an Electron preload script, document will be defined but not fully - // initialized. Since we know we're in Chrome, we'll just detect this case - // explicitly - if (typeof window !== 'undefined' && window.process && window.process.type === 'renderer') { - return true; - } - - // is webkit? http://stackoverflow.com/a/16459606/376773 - // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632 - return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) || - // is firebug? http://stackoverflow.com/a/398120/376773 - (typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) || - // is firefox >= v31? - // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages - (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) || - // double check webkit in userAgent just in case we are in a worker - (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/)); -} - -/** - * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. - */ - -exports.formatters.j = function(v) { - try { - return JSON.stringify(v); - } catch (err) { - return '[UnexpectedJSONParseError]: ' + err.message; - } -}; - - -/** - * Colorize log arguments if enabled. - * - * @api public - */ - -function formatArgs(args) { - var useColors = this.useColors; - - args[0] = (useColors ? '%c' : '') - + this.namespace - + (useColors ? ' %c' : ' ') - + args[0] - + (useColors ? '%c ' : ' ') - + '+' + exports.humanize(this.diff); - - if (!useColors) return; - - var c = 'color: ' + this.color; - args.splice(1, 0, c, 'color: inherit') - - // the final "%c" is somewhat tricky, because there could be other - // arguments passed either before or after the %c, so we need to - // figure out the correct index to insert the CSS into - var index = 0; - var lastC = 0; - args[0].replace(/%[a-zA-Z%]/g, function(match) { - if ('%%' === match) return; - index++; - if ('%c' === match) { - // we only are interested in the *last* %c - // (the user may have provided their own) - lastC = index; - } - }); - - args.splice(lastC, 0, c); -} - -/** - * Invokes `console.log()` when available. - * No-op when `console.log` is not a "function". - * - * @api public - */ - -function log() { - // this hackery is required for IE8/9, where - // the `console.log` function doesn't have 'apply' - return 'object' === typeof console - && console.log - && Function.prototype.apply.call(console.log, console, arguments); -} - -/** - * Save `namespaces`. - * - * @param {String} namespaces - * @api private - */ - -function save(namespaces) { - try { - if (null == namespaces) { - exports.storage.removeItem('debug'); - } else { - exports.storage.debug = namespaces; - } - } catch(e) {} -} - -/** - * Load `namespaces`. - * - * @return {String} returns the previously persisted debug modes - * @api private - */ - -function load() { - var r; - try { - r = exports.storage.debug; - } catch(e) {} - - // If debug isn't set in LS, and we're in Electron, try to load $DEBUG - if (!r && typeof process !== 'undefined' && 'env' in process) { - r = process.env.DEBUG; - } - - return r; -} - -/** - * Enable namespaces listed in `localStorage.debug` initially. - */ - -exports.enable(load()); - -/** - * Localstorage attempts to return the localstorage. - * - * This is necessary because safari throws - * when a user disables cookies/localstorage - * and you attempt to access it. - * - * @return {LocalStorage} - * @api private - */ - -function localstorage() { - try { - return window.localStorage; - } catch (e) {} -} - - -/***/ }), -/* 866 */ -/***/ (function(module, exports, __webpack_require__) { - - -/** - * This is the common logic for both the Node.js and web browser - * implementations of `debug()`. - * - * Expose `debug()` as the module. - */ - -exports = module.exports = createDebug.debug = createDebug['default'] = createDebug; -exports.coerce = coerce; -exports.disable = disable; -exports.enable = enable; -exports.enabled = enabled; -exports.humanize = __webpack_require__(867); - -/** - * The currently active debug mode names, and names to skip. - */ - -exports.names = []; -exports.skips = []; - -/** - * Map of special "%n" handling functions, for the debug "format" argument. - * - * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N". - */ - -exports.formatters = {}; - -/** - * Previous log timestamp. - */ - -var prevTime; - -/** - * Select a color. - * @param {String} namespace - * @return {Number} - * @api private - */ - -function selectColor(namespace) { - var hash = 0, i; - - for (i in namespace) { - hash = ((hash << 5) - hash) + namespace.charCodeAt(i); - hash |= 0; // Convert to 32bit integer - } - - return exports.colors[Math.abs(hash) % exports.colors.length]; -} - -/** - * Create a debugger with the given `namespace`. - * - * @param {String} namespace - * @return {Function} - * @api public - */ - -function createDebug(namespace) { - - function debug() { - // disabled? - if (!debug.enabled) return; - - var self = debug; - - // set `diff` timestamp - var curr = +new Date(); - var ms = curr - (prevTime || curr); - self.diff = ms; - self.prev = prevTime; - self.curr = curr; - prevTime = curr; - - // turn the `arguments` into a proper Array - var args = new Array(arguments.length); - for (var i = 0; i < args.length; i++) { - args[i] = arguments[i]; - } - - args[0] = exports.coerce(args[0]); - - if ('string' !== typeof args[0]) { - // anything else let's inspect with %O - args.unshift('%O'); - } - - // apply any `formatters` transformations - var index = 0; - args[0] = args[0].replace(/%([a-zA-Z%])/g, function(match, format) { - // if we encounter an escaped % then don't increase the array index - if (match === '%%') return match; - index++; - var formatter = exports.formatters[format]; - if ('function' === typeof formatter) { - var val = args[index]; - match = formatter.call(self, val); - - // now we need to remove `args[index]` since it's inlined in the `format` - args.splice(index, 1); - index--; - } - return match; - }); - - // apply env-specific formatting (colors, etc.) - exports.formatArgs.call(self, args); - - var logFn = debug.log || exports.log || console.log.bind(console); - logFn.apply(self, args); - } - - debug.namespace = namespace; - debug.enabled = exports.enabled(namespace); - debug.useColors = exports.useColors(); - debug.color = selectColor(namespace); - - // env-specific initialization logic for debug instances - if ('function' === typeof exports.init) { - exports.init(debug); - } - - return debug; -} - -/** - * Enables a debug mode by namespaces. This can include modes - * separated by a colon and wildcards. - * - * @param {String} namespaces - * @api public - */ - -function enable(namespaces) { - exports.save(namespaces); - - exports.names = []; - exports.skips = []; - - var split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/); - var len = split.length; - - for (var i = 0; i < len; i++) { - if (!split[i]) continue; // ignore empty strings - namespaces = split[i].replace(/\*/g, '.*?'); - if (namespaces[0] === '-') { - exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$')); - } else { - exports.names.push(new RegExp('^' + namespaces + '$')); - } - } -} - -/** - * Disable debug output. - * - * @api public - */ - -function disable() { - exports.enable(''); -} - -/** - * Returns true if the given mode name is enabled, false otherwise. - * - * @param {String} name - * @return {Boolean} - * @api public - */ - -function enabled(name) { - var i, len; - for (i = 0, len = exports.skips.length; i < len; i++) { - if (exports.skips[i].test(name)) { - return false; - } - } - for (i = 0, len = exports.names.length; i < len; i++) { - if (exports.names[i].test(name)) { - return true; - } - } - return false; -} - -/** - * Coerce `val`. - * - * @param {Mixed} val - * @return {Mixed} - * @api private - */ - -function coerce(val) { - if (val instanceof Error) return val.stack || val.message; - return val; -} - - -/***/ }), -/* 867 */ -/***/ (function(module, exports) { - -/** - * Helpers. - */ - -var s = 1000; -var m = s * 60; -var h = m * 60; -var d = h * 24; -var y = d * 365.25; - -/** - * Parse or format the given `val`. - * - * Options: - * - * - `long` verbose formatting [false] - * - * @param {String|Number} val - * @param {Object} [options] - * @throws {Error} throw an error if val is not a non-empty string or a number - * @return {String|Number} - * @api public - */ - -module.exports = function(val, options) { - options = options || {}; - var type = typeof val; - if (type === 'string' && val.length > 0) { - return parse(val); - } else if (type === 'number' && isNaN(val) === false) { - return options.long ? fmtLong(val) : fmtShort(val); - } - throw new Error( - 'val is not a non-empty string or a valid number. val=' + - JSON.stringify(val) - ); -}; - -/** - * Parse the given `str` and return milliseconds. - * - * @param {String} str - * @return {Number} - * @api private - */ - -function parse(str) { - str = String(str); - if (str.length > 100) { - return; - } - var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec( - str - ); - if (!match) { - return; - } - var n = parseFloat(match[1]); - var type = (match[2] || 'ms').toLowerCase(); - switch (type) { - case 'years': - case 'year': - case 'yrs': - case 'yr': - case 'y': - return n * y; - case 'days': - case 'day': - case 'd': - return n * d; - case 'hours': - case 'hour': - case 'hrs': - case 'hr': - case 'h': - return n * h; - case 'minutes': - case 'minute': - case 'mins': - case 'min': - case 'm': - return n * m; - case 'seconds': - case 'second': - case 'secs': - case 'sec': - case 's': - return n * s; - case 'milliseconds': - case 'millisecond': - case 'msecs': - case 'msec': - case 'ms': - return n; - default: - return undefined; - } -} - -/** - * Short format for `ms`. - * - * @param {Number} ms - * @return {String} - * @api private - */ - -function fmtShort(ms) { - if (ms >= d) { - return Math.round(ms / d) + 'd'; - } - if (ms >= h) { - return Math.round(ms / h) + 'h'; - } - if (ms >= m) { - return Math.round(ms / m) + 'm'; - } - if (ms >= s) { - return Math.round(ms / s) + 's'; - } - return ms + 'ms'; -} - -/** - * Long format for `ms`. - * - * @param {Number} ms - * @return {String} - * @api private - */ - -function fmtLong(ms) { - return plural(ms, d, 'day') || - plural(ms, h, 'hour') || - plural(ms, m, 'minute') || - plural(ms, s, 'second') || - ms + ' ms'; -} - -/** - * Pluralization helper. - */ - -function plural(ms, n, name) { - if (ms < n) { - return; - } - if (ms < n * 1.5) { - return Math.floor(ms / n) + ' ' + name; - } - return Math.ceil(ms / n) + ' ' + name + 's'; -} - - -/***/ }), -/* 868 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * Module dependencies. - */ - -var tty = __webpack_require__(478); -var util = __webpack_require__(29); - -/** - * This is the Node.js implementation of `debug()`. - * - * Expose `debug()` as the module. - */ - -exports = module.exports = __webpack_require__(866); -exports.init = init; -exports.log = log; -exports.formatArgs = formatArgs; -exports.save = save; -exports.load = load; -exports.useColors = useColors; - -/** - * Colors. - */ - -exports.colors = [6, 2, 3, 4, 5, 1]; - -/** - * Build up the default `inspectOpts` object from the environment variables. - * - * $ DEBUG_COLORS=no DEBUG_DEPTH=10 DEBUG_SHOW_HIDDEN=enabled node script.js - */ - -exports.inspectOpts = Object.keys(process.env).filter(function (key) { - return /^debug_/i.test(key); -}).reduce(function (obj, key) { - // camel-case - var prop = key - .substring(6) - .toLowerCase() - .replace(/_([a-z])/g, function (_, k) { return k.toUpperCase() }); - - // coerce string value into JS value - var val = process.env[key]; - if (/^(yes|on|true|enabled)$/i.test(val)) val = true; - else if (/^(no|off|false|disabled)$/i.test(val)) val = false; - else if (val === 'null') val = null; - else val = Number(val); - - obj[prop] = val; - return obj; -}, {}); - -/** - * The file descriptor to write the `debug()` calls to. - * Set the `DEBUG_FD` env variable to override with another value. i.e.: - * - * $ DEBUG_FD=3 node script.js 3>debug.log - */ - -var fd = parseInt(process.env.DEBUG_FD, 10) || 2; - -if (1 !== fd && 2 !== fd) { - util.deprecate(function(){}, 'except for stderr(2) and stdout(1), any other usage of DEBUG_FD is deprecated. Override debug.log if you want to use a different log function (https://git.io/debug_fd)')() -} - -var stream = 1 === fd ? process.stdout : - 2 === fd ? process.stderr : - createWritableStdioStream(fd); - -/** - * Is stdout a TTY? Colored output is enabled when `true`. - */ - -function useColors() { - return 'colors' in exports.inspectOpts - ? Boolean(exports.inspectOpts.colors) - : tty.isatty(fd); -} - -/** - * Map %o to `util.inspect()`, all on a single line. - */ - -exports.formatters.o = function(v) { - this.inspectOpts.colors = this.useColors; - return util.inspect(v, this.inspectOpts) - .split('\n').map(function(str) { - return str.trim() - }).join(' '); -}; - -/** - * Map %o to `util.inspect()`, allowing multiple lines if needed. - */ - -exports.formatters.O = function(v) { - this.inspectOpts.colors = this.useColors; - return util.inspect(v, this.inspectOpts); -}; - -/** - * Adds ANSI color escape codes if enabled. - * - * @api public - */ - -function formatArgs(args) { - var name = this.namespace; - var useColors = this.useColors; - - if (useColors) { - var c = this.color; - var prefix = ' \u001b[3' + c + ';1m' + name + ' ' + '\u001b[0m'; - - args[0] = prefix + args[0].split('\n').join('\n' + prefix); - args.push('\u001b[3' + c + 'm+' + exports.humanize(this.diff) + '\u001b[0m'); - } else { - args[0] = new Date().toUTCString() - + ' ' + name + ' ' + args[0]; - } -} - -/** - * Invokes `util.format()` with the specified arguments and writes to `stream`. - */ - -function log() { - return stream.write(util.format.apply(util, arguments) + '\n'); -} - -/** - * Save `namespaces`. - * - * @param {String} namespaces - * @api private - */ - -function save(namespaces) { - if (null == namespaces) { - // If you set a process.env field to null or undefined, it gets cast to the - // string 'null' or 'undefined'. Just delete instead. - delete process.env.DEBUG; - } else { - process.env.DEBUG = namespaces; - } -} - -/** - * Load `namespaces`. - * - * @return {String} returns the previously persisted debug modes - * @api private - */ - -function load() { - return process.env.DEBUG; -} - -/** - * Copied from `node/src/node.js`. - * - * XXX: It's lame that node doesn't expose this API out-of-the-box. It also - * relies on the undocumented `tty_wrap.guessHandleType()` which is also lame. - */ - -function createWritableStdioStream (fd) { - var stream; - var tty_wrap = process.binding('tty_wrap'); - - // Note stream._type is used for test-module-load-list.js - - switch (tty_wrap.guessHandleType(fd)) { - case 'TTY': - stream = new tty.WriteStream(fd); - stream._type = 'tty'; - - // Hack to have stream not keep the event loop alive. - // See https://github.com/joyent/node/issues/1726 - if (stream._handle && stream._handle.unref) { - stream._handle.unref(); - } - break; - - case 'FILE': - var fs = __webpack_require__(23); - stream = new fs.SyncWriteStream(fd, { autoClose: false }); - stream._type = 'fs'; - break; - - case 'PIPE': - case 'TCP': - var net = __webpack_require__(806); - stream = new net.Socket({ - fd: fd, - readable: false, - writable: true - }); - - // FIXME Should probably have an option in net.Socket to create a - // stream from an existing fd which is writable only. But for now - // we'll just add this hack and set the `readable` member to false. - // Test: ./node test/fixtures/echo.js < /etc/passwd - stream.readable = false; - stream.read = null; - stream._type = 'pipe'; - - // FIXME Hack to have stream not keep the event loop alive. - // See https://github.com/joyent/node/issues/1726 - if (stream._handle && stream._handle.unref) { - stream._handle.unref(); - } - break; - - default: - // Probably an error on in uv_guess_handle() - throw new Error('Implement me. Unknown stream file type!'); - } - - // For supporting legacy API we put the FD here. - stream.fd = fd; - - stream._isStdio = true; - - return stream; -} - -/** - * Init logic for `debug` instances. - * - * Create a new `inspectOpts` object in case `useColors` is set - * differently for a particular `debug` instance. - */ - -function init (debug) { - debug.inspectOpts = {}; - - var keys = Object.keys(exports.inspectOpts); - for (var i = 0; i < keys.length; i++) { - debug.inspectOpts[keys[i]] = exports.inspectOpts[keys[i]]; - } -} - -/** - * Enable namespaces listed in `process.env.DEBUG` initially. - */ - -exports.enable(load()); - - -/***/ }), -/* 869 */ -/***/ (function(module, exports, __webpack_require__) { - "use strict"; var brackets = __webpack_require__(859); -var define = __webpack_require__(870); -var utils = __webpack_require__(871); +var define = __webpack_require__(865); +var utils = __webpack_require__(866); /** * Characters to use in text regex (we want to "not" match @@ -102803,7 +101976,7 @@ module.exports = parsers; /***/ }), -/* 870 */ +/* 865 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -102841,7 +102014,7 @@ module.exports = function defineProperty(obj, prop, val) { /***/ }), -/* 871 */ +/* 866 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -102917,7 +102090,7 @@ utils.createRegex = function(str) { /***/ }), -/* 872 */ +/* 867 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -102928,7 +102101,7 @@ utils.createRegex = function(str) { */ var Snapdragon = __webpack_require__(768); -var define = __webpack_require__(870); +var define = __webpack_require__(865); var extend = __webpack_require__(738); /** @@ -102936,7 +102109,7 @@ var extend = __webpack_require__(738); */ var compilers = __webpack_require__(858); -var parsers = __webpack_require__(869); +var parsers = __webpack_require__(864); /** * Customize Snapdragon parser and renderer @@ -103002,7 +102175,7 @@ module.exports = Extglob; /***/ }), -/* 873 */ +/* 868 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -103092,14 +102265,14 @@ function textRegex(pattern) { /***/ }), -/* 874 */ +/* 869 */ /***/ (function(module, exports, __webpack_require__) { module.exports = new (__webpack_require__(850))(); /***/ }), -/* 875 */ +/* 870 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -103117,7 +102290,7 @@ utils.define = __webpack_require__(837); utils.diff = __webpack_require__(854); utils.extend = __webpack_require__(838); utils.pick = __webpack_require__(855); -utils.typeOf = __webpack_require__(876); +utils.typeOf = __webpack_require__(871); utils.unique = __webpack_require__(741); /** @@ -103415,7 +102588,7 @@ utils.unixify = function(options) { /***/ }), -/* 876 */ +/* 871 */ /***/ (function(module, exports) { var toString = Object.prototype.toString; @@ -103550,7 +102723,7 @@ function isBuffer(val) { /***/ }), -/* 877 */ +/* 872 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -103569,9 +102742,9 @@ var __extends = (this && this.__extends) || (function () { }; })(); Object.defineProperty(exports, "__esModule", { value: true }); -var readdir = __webpack_require__(878); -var reader_1 = __webpack_require__(891); -var fs_stream_1 = __webpack_require__(895); +var readdir = __webpack_require__(873); +var reader_1 = __webpack_require__(886); +var fs_stream_1 = __webpack_require__(890); var ReaderAsync = /** @class */ (function (_super) { __extends(ReaderAsync, _super); function ReaderAsync() { @@ -103632,15 +102805,15 @@ exports.default = ReaderAsync; /***/ }), -/* 878 */ +/* 873 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const readdirSync = __webpack_require__(879); -const readdirAsync = __webpack_require__(887); -const readdirStream = __webpack_require__(890); +const readdirSync = __webpack_require__(874); +const readdirAsync = __webpack_require__(882); +const readdirStream = __webpack_require__(885); module.exports = exports = readdirAsyncPath; exports.readdir = exports.readdirAsync = exports.async = readdirAsyncPath; @@ -103724,7 +102897,7 @@ function readdirStreamStat (dir, options) { /***/ }), -/* 879 */ +/* 874 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -103732,11 +102905,11 @@ function readdirStreamStat (dir, options) { module.exports = readdirSync; -const DirectoryReader = __webpack_require__(880); +const DirectoryReader = __webpack_require__(875); let syncFacade = { - fs: __webpack_require__(885), - forEach: __webpack_require__(886), + fs: __webpack_require__(880), + forEach: __webpack_require__(881), sync: true }; @@ -103765,7 +102938,7 @@ function readdirSync (dir, options, internalOptions) { /***/ }), -/* 880 */ +/* 875 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -103774,9 +102947,9 @@ function readdirSync (dir, options, internalOptions) { const Readable = __webpack_require__(27).Readable; const EventEmitter = __webpack_require__(379).EventEmitter; const path = __webpack_require__(16); -const normalizeOptions = __webpack_require__(881); -const stat = __webpack_require__(883); -const call = __webpack_require__(884); +const normalizeOptions = __webpack_require__(876); +const stat = __webpack_require__(878); +const call = __webpack_require__(879); /** * Asynchronously reads the contents of a directory and streams the results @@ -104152,14 +103325,14 @@ module.exports = DirectoryReader; /***/ }), -/* 881 */ +/* 876 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const path = __webpack_require__(16); -const globToRegExp = __webpack_require__(882); +const globToRegExp = __webpack_require__(877); module.exports = normalizeOptions; @@ -104336,7 +103509,7 @@ function normalizeOptions (options, internalOptions) { /***/ }), -/* 882 */ +/* 877 */ /***/ (function(module, exports) { module.exports = function (glob, opts) { @@ -104473,13 +103646,13 @@ module.exports = function (glob, opts) { /***/ }), -/* 883 */ +/* 878 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const call = __webpack_require__(884); +const call = __webpack_require__(879); module.exports = stat; @@ -104554,7 +103727,7 @@ function symlinkStat (fs, path, lstats, callback) { /***/ }), -/* 884 */ +/* 879 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -104615,14 +103788,14 @@ function callOnce (fn) { /***/ }), -/* 885 */ +/* 880 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const fs = __webpack_require__(23); -const call = __webpack_require__(884); +const call = __webpack_require__(879); /** * A facade around {@link fs.readdirSync} that allows it to be called @@ -104686,7 +103859,7 @@ exports.lstat = function (path, callback) { /***/ }), -/* 886 */ +/* 881 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -104715,7 +103888,7 @@ function syncForEach (array, iterator, done) { /***/ }), -/* 887 */ +/* 882 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -104723,12 +103896,12 @@ function syncForEach (array, iterator, done) { module.exports = readdirAsync; -const maybe = __webpack_require__(888); -const DirectoryReader = __webpack_require__(880); +const maybe = __webpack_require__(883); +const DirectoryReader = __webpack_require__(875); let asyncFacade = { fs: __webpack_require__(23), - forEach: __webpack_require__(889), + forEach: __webpack_require__(884), async: true }; @@ -104770,7 +103943,7 @@ function readdirAsync (dir, options, callback, internalOptions) { /***/ }), -/* 888 */ +/* 883 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -104797,7 +103970,7 @@ module.exports = function maybe (cb, promise) { /***/ }), -/* 889 */ +/* 884 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -104833,7 +104006,7 @@ function asyncForEach (array, iterator, done) { /***/ }), -/* 890 */ +/* 885 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -104841,11 +104014,11 @@ function asyncForEach (array, iterator, done) { module.exports = readdirStream; -const DirectoryReader = __webpack_require__(880); +const DirectoryReader = __webpack_require__(875); let streamFacade = { fs: __webpack_require__(23), - forEach: __webpack_require__(889), + forEach: __webpack_require__(884), async: true }; @@ -104865,16 +104038,16 @@ function readdirStream (dir, options, internalOptions) { /***/ }), -/* 891 */ +/* 886 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var path = __webpack_require__(16); -var deep_1 = __webpack_require__(892); -var entry_1 = __webpack_require__(894); -var pathUtil = __webpack_require__(893); +var deep_1 = __webpack_require__(887); +var entry_1 = __webpack_require__(889); +var pathUtil = __webpack_require__(888); var Reader = /** @class */ (function () { function Reader(options) { this.options = options; @@ -104940,13 +104113,13 @@ exports.default = Reader; /***/ }), -/* 892 */ +/* 887 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var pathUtils = __webpack_require__(893); +var pathUtils = __webpack_require__(888); var patternUtils = __webpack_require__(722); var DeepFilter = /** @class */ (function () { function DeepFilter(options, micromatchOptions) { @@ -105030,7 +104203,7 @@ exports.default = DeepFilter; /***/ }), -/* 893 */ +/* 888 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -105061,13 +104234,13 @@ exports.makeAbsolute = makeAbsolute; /***/ }), -/* 894 */ +/* 889 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var pathUtils = __webpack_require__(893); +var pathUtils = __webpack_require__(888); var patternUtils = __webpack_require__(722); var EntryFilter = /** @class */ (function () { function EntryFilter(options, micromatchOptions) { @@ -105153,7 +104326,7 @@ exports.default = EntryFilter; /***/ }), -/* 895 */ +/* 890 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -105173,8 +104346,8 @@ var __extends = (this && this.__extends) || (function () { })(); Object.defineProperty(exports, "__esModule", { value: true }); var stream = __webpack_require__(27); -var fsStat = __webpack_require__(896); -var fs_1 = __webpack_require__(900); +var fsStat = __webpack_require__(891); +var fs_1 = __webpack_require__(895); var FileSystemStream = /** @class */ (function (_super) { __extends(FileSystemStream, _super); function FileSystemStream() { @@ -105224,14 +104397,14 @@ exports.default = FileSystemStream; /***/ }), -/* 896 */ +/* 891 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const optionsManager = __webpack_require__(897); -const statProvider = __webpack_require__(899); +const optionsManager = __webpack_require__(892); +const statProvider = __webpack_require__(894); /** * Asynchronous API. */ @@ -105262,13 +104435,13 @@ exports.statSync = statSync; /***/ }), -/* 897 */ +/* 892 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const fsAdapter = __webpack_require__(898); +const fsAdapter = __webpack_require__(893); function prepare(opts) { const options = Object.assign({ fs: fsAdapter.getFileSystemAdapter(opts ? opts.fs : undefined), @@ -105281,7 +104454,7 @@ exports.prepare = prepare; /***/ }), -/* 898 */ +/* 893 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -105304,7 +104477,7 @@ exports.getFileSystemAdapter = getFileSystemAdapter; /***/ }), -/* 899 */ +/* 894 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -105356,7 +104529,7 @@ exports.isFollowedSymlink = isFollowedSymlink; /***/ }), -/* 900 */ +/* 895 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -105387,7 +104560,7 @@ exports.default = FileSystem; /***/ }), -/* 901 */ +/* 896 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -105407,9 +104580,9 @@ var __extends = (this && this.__extends) || (function () { })(); Object.defineProperty(exports, "__esModule", { value: true }); var stream = __webpack_require__(27); -var readdir = __webpack_require__(878); -var reader_1 = __webpack_require__(891); -var fs_stream_1 = __webpack_require__(895); +var readdir = __webpack_require__(873); +var reader_1 = __webpack_require__(886); +var fs_stream_1 = __webpack_require__(890); var TransformStream = /** @class */ (function (_super) { __extends(TransformStream, _super); function TransformStream(reader) { @@ -105477,7 +104650,7 @@ exports.default = ReaderStream; /***/ }), -/* 902 */ +/* 897 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -105496,9 +104669,9 @@ var __extends = (this && this.__extends) || (function () { }; })(); Object.defineProperty(exports, "__esModule", { value: true }); -var readdir = __webpack_require__(878); -var reader_1 = __webpack_require__(891); -var fs_sync_1 = __webpack_require__(903); +var readdir = __webpack_require__(873); +var reader_1 = __webpack_require__(886); +var fs_sync_1 = __webpack_require__(898); var ReaderSync = /** @class */ (function (_super) { __extends(ReaderSync, _super); function ReaderSync() { @@ -105558,7 +104731,7 @@ exports.default = ReaderSync; /***/ }), -/* 903 */ +/* 898 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -105577,8 +104750,8 @@ var __extends = (this && this.__extends) || (function () { }; })(); Object.defineProperty(exports, "__esModule", { value: true }); -var fsStat = __webpack_require__(896); -var fs_1 = __webpack_require__(900); +var fsStat = __webpack_require__(891); +var fs_1 = __webpack_require__(895); var FileSystemSync = /** @class */ (function (_super) { __extends(FileSystemSync, _super); function FileSystemSync() { @@ -105624,7 +104797,7 @@ exports.default = FileSystemSync; /***/ }), -/* 904 */ +/* 899 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -105640,7 +104813,7 @@ exports.flatten = flatten; /***/ }), -/* 905 */ +/* 900 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -105661,13 +104834,13 @@ exports.merge = merge; /***/ }), -/* 906 */ +/* 901 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const path = __webpack_require__(16); -const pathType = __webpack_require__(907); +const pathType = __webpack_require__(902); const getExtensions = extensions => extensions.length > 1 ? `{${extensions.join(',')}}` : extensions[0]; @@ -105733,13 +104906,13 @@ module.exports.sync = (input, opts) => { /***/ }), -/* 907 */ +/* 902 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const fs = __webpack_require__(23); -const pify = __webpack_require__(908); +const pify = __webpack_require__(903); function type(fn, fn2, fp) { if (typeof fp !== 'string') { @@ -105782,7 +104955,7 @@ exports.symlinkSync = typeSync.bind(null, 'lstatSync', 'isSymbolicLink'); /***/ }), -/* 908 */ +/* 903 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -105873,7 +105046,7 @@ module.exports = (obj, opts) => { /***/ }), -/* 909 */ +/* 904 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -105881,9 +105054,9 @@ module.exports = (obj, opts) => { const fs = __webpack_require__(23); const path = __webpack_require__(16); const fastGlob = __webpack_require__(718); -const gitIgnore = __webpack_require__(910); -const pify = __webpack_require__(911); -const slash = __webpack_require__(912); +const gitIgnore = __webpack_require__(905); +const pify = __webpack_require__(906); +const slash = __webpack_require__(907); const DEFAULT_IGNORE = [ '**/node_modules/**', @@ -105981,7 +105154,7 @@ module.exports.sync = options => { /***/ }), -/* 910 */ +/* 905 */ /***/ (function(module, exports) { // A simple implementation of make-array @@ -106450,7 +105623,7 @@ module.exports = options => new IgnoreBase(options) /***/ }), -/* 911 */ +/* 906 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -106525,7 +105698,7 @@ module.exports = (input, options) => { /***/ }), -/* 912 */ +/* 907 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -106543,17 +105716,17 @@ module.exports = input => { /***/ }), -/* 913 */ +/* 908 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const path = __webpack_require__(16); const {constants: fsConstants} = __webpack_require__(23); -const pEvent = __webpack_require__(914); -const CpFileError = __webpack_require__(917); -const fs = __webpack_require__(921); -const ProgressEmitter = __webpack_require__(924); +const pEvent = __webpack_require__(909); +const CpFileError = __webpack_require__(912); +const fs = __webpack_require__(916); +const ProgressEmitter = __webpack_require__(919); const cpFileAsync = async (source, destination, options, progressEmitter) => { let readError; @@ -106667,12 +105840,12 @@ module.exports.sync = (source, destination, options) => { /***/ }), -/* 914 */ +/* 909 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const pTimeout = __webpack_require__(915); +const pTimeout = __webpack_require__(910); const symbolAsyncIterator = Symbol.asyncIterator || '@@asyncIterator'; @@ -106963,12 +106136,12 @@ module.exports.iterator = (emitter, event, options) => { /***/ }), -/* 915 */ +/* 910 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const pFinally = __webpack_require__(916); +const pFinally = __webpack_require__(911); class TimeoutError extends Error { constructor(message) { @@ -107014,7 +106187,7 @@ module.exports.TimeoutError = TimeoutError; /***/ }), -/* 916 */ +/* 911 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -107036,12 +106209,12 @@ module.exports = (promise, onFinally) => { /***/ }), -/* 917 */ +/* 912 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const NestedError = __webpack_require__(918); +const NestedError = __webpack_require__(913); class CpFileError extends NestedError { constructor(message, nested) { @@ -107055,10 +106228,10 @@ module.exports = CpFileError; /***/ }), -/* 918 */ +/* 913 */ /***/ (function(module, exports, __webpack_require__) { -var inherits = __webpack_require__(919); +var inherits = __webpack_require__(914); var NestedError = function (message, nested) { this.nested = nested; @@ -107109,7 +106282,7 @@ module.exports = NestedError; /***/ }), -/* 919 */ +/* 914 */ /***/ (function(module, exports, __webpack_require__) { try { @@ -107117,12 +106290,12 @@ try { if (typeof util.inherits !== 'function') throw ''; module.exports = util.inherits; } catch (e) { - module.exports = __webpack_require__(920); + module.exports = __webpack_require__(915); } /***/ }), -/* 920 */ +/* 915 */ /***/ (function(module, exports) { if (typeof Object.create === 'function') { @@ -107151,16 +106324,16 @@ if (typeof Object.create === 'function') { /***/ }), -/* 921 */ +/* 916 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const {promisify} = __webpack_require__(29); const fs = __webpack_require__(22); -const makeDir = __webpack_require__(922); -const pEvent = __webpack_require__(914); -const CpFileError = __webpack_require__(917); +const makeDir = __webpack_require__(917); +const pEvent = __webpack_require__(909); +const CpFileError = __webpack_require__(912); const stat = promisify(fs.stat); const lstat = promisify(fs.lstat); @@ -107257,7 +106430,7 @@ exports.copyFileSync = (source, destination, flags) => { /***/ }), -/* 922 */ +/* 917 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -107265,7 +106438,7 @@ exports.copyFileSync = (source, destination, flags) => { const fs = __webpack_require__(23); const path = __webpack_require__(16); const {promisify} = __webpack_require__(29); -const semver = __webpack_require__(923); +const semver = __webpack_require__(918); const defaults = { mode: 0o777 & (~process.umask()), @@ -107414,7 +106587,7 @@ module.exports.sync = (input, options) => { /***/ }), -/* 923 */ +/* 918 */ /***/ (function(module, exports) { exports = module.exports = SemVer @@ -109016,7 +108189,7 @@ function coerce (version, options) { /***/ }), -/* 924 */ +/* 919 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -109057,7 +108230,7 @@ module.exports = ProgressEmitter; /***/ }), -/* 925 */ +/* 920 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -109103,12 +108276,12 @@ exports.default = module.exports; /***/ }), -/* 926 */ +/* 921 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const NestedError = __webpack_require__(927); +const NestedError = __webpack_require__(922); class CpyError extends NestedError { constructor(message, nested) { @@ -109122,7 +108295,7 @@ module.exports = CpyError; /***/ }), -/* 927 */ +/* 922 */ /***/ (function(module, exports, __webpack_require__) { var inherits = __webpack_require__(29).inherits; @@ -109178,7 +108351,7 @@ module.exports = NestedError; /***/ }), -/* 928 */ +/* 923 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; diff --git a/packages/kbn-test/src/functional_test_runner/lib/config/schema.ts b/packages/kbn-test/src/functional_test_runner/lib/config/schema.ts index 66f17ab579ec3..f4b91d154cbb8 100644 --- a/packages/kbn-test/src/functional_test_runner/lib/config/schema.ts +++ b/packages/kbn-test/src/functional_test_runner/lib/config/schema.ts @@ -136,7 +136,7 @@ export const schema = Joi.object() browser: Joi.object() .keys({ type: Joi.string() - .valid('chrome', 'firefox', 'ie') + .valid('chrome', 'firefox', 'ie', 'msedge') .default('chrome'), logPollingMs: Joi.number().default(100), diff --git a/test/functional/config.edge.js b/test/functional/config.edge.js new file mode 100644 index 0000000000000..ed68b41e8c89a --- /dev/null +++ b/test/functional/config.edge.js @@ -0,0 +1,34 @@ +/* + * 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 async function({ readConfigFile }) { + const defaultConfig = await readConfigFile(require.resolve('./config')); + + return { + ...defaultConfig.getAll(), + + browser: { + type: 'msedge', + }, + + junit: { + reportName: 'MS Chromium Edge UI Functional Tests', + }, + }; +} diff --git a/test/functional/services/browser.ts b/test/functional/services/browser.ts index 5017947e95d03..13d2365c07191 100644 --- a/test/functional/services/browser.ts +++ b/test/functional/services/browser.ts @@ -47,7 +47,9 @@ export async function BrowserProvider({ getService }: FtrProviderContext) { */ public readonly browserType: string = browserType; - public readonly isChrome: boolean = browserType === Browsers.Chrome; + public readonly isChromium: boolean = [Browsers.Chrome, Browsers.ChromiumEdge].includes( + browserType + ); public readonly isFirefox: boolean = browserType === Browsers.Firefox; diff --git a/test/functional/services/lib/web_element_wrapper/web_element_wrapper.ts b/test/functional/services/lib/web_element_wrapper/web_element_wrapper.ts index 157918df874c8..8b57ecd3c8235 100644 --- a/test/functional/services/lib/web_element_wrapper/web_element_wrapper.ts +++ b/test/functional/services/lib/web_element_wrapper/web_element_wrapper.ts @@ -55,6 +55,7 @@ export class WebElementWrapper { private driver: WebDriver = this.webDriver.driver; private Keys = Key; public isW3CEnabled: boolean = (this.webDriver.driver as any).executor_.w3c === true; + public isChromium: boolean = [Browsers.Chrome, Browsers.ChromiumEdge].includes(this.browserType); public static create( webElement: WebElement | WebElementWrapper, @@ -63,7 +64,7 @@ export class WebElementWrapper { timeout: number, fixedHeaderHeight: number, logger: ToolingLog, - browserType: string + browserType: Browsers ): WebElementWrapper { if (webElement instanceof WebElementWrapper) { return webElement; @@ -87,7 +88,7 @@ export class WebElementWrapper { private timeout: number, private fixedHeaderHeight: number, private logger: ToolingLog, - private browserType: string + private browserType: Browsers ) {} private async _findWithCustomTimeout( @@ -243,7 +244,7 @@ export class WebElementWrapper { return this.clearValueWithKeyboard(); } await this.retryCall(async function clearValue(wrapper) { - if (wrapper.browserType === Browsers.Chrome || options.withJS) { + if (wrapper.isChromium || options.withJS) { // https://bugs.chromium.org/p/chromedriver/issues/detail?id=2702 await wrapper.driver.executeScript(`arguments[0].value=''`, wrapper._webElement); } else { @@ -275,7 +276,7 @@ export class WebElementWrapper { await delay(100); } } else { - if (this.browserType === Browsers.Chrome) { + if (this.isChromium) { // https://bugs.chromium.org/p/chromedriver/issues/detail?id=30 await this.retryCall(async function clearValueWithKeyboard(wrapper) { await wrapper.driver.executeScript(`arguments[0].select();`, wrapper._webElement); diff --git a/test/functional/services/remote/browsers.ts b/test/functional/services/remote/browsers.ts index 46d81f1737a55..aa6e364d0a09d 100644 --- a/test/functional/services/remote/browsers.ts +++ b/test/functional/services/remote/browsers.ts @@ -21,4 +21,5 @@ export enum Browsers { Chrome = 'chrome', Firefox = 'firefox', InternetExplorer = 'ie', + ChromiumEdge = 'msedge', } diff --git a/test/functional/services/remote/remote.ts b/test/functional/services/remote/remote.ts index e571a1a7e5551..b0724488cb5db 100644 --- a/test/functional/services/remote/remote.ts +++ b/test/functional/services/remote/remote.ts @@ -64,18 +64,23 @@ export async function RemoteProvider({ getService }: FtrProviderContext) { lifecycle, config.get('browser.logPollingMs') ); + const isW3CEnabled = (driver as any).executor_.w3c; const caps = await driver.getCapabilities(); - const browserVersion = caps.get(isW3CEnabled ? 'browserVersion' : 'version'); + const browserVersion = caps.get( + isW3CEnabled || browserType === Browsers.ChromiumEdge ? 'browserVersion' : 'version' + ); - log.info(`Remote initialized: ${caps.get('browserName')} ${browserVersion}`); + log.info( + `Remote initialized: ${caps.get( + 'browserName' + )} ${browserVersion}, w3c compliance=${isW3CEnabled}, collectingCoverage=${collectCoverage}` + ); - if (browserType === Browsers.Chrome) { + if ([Browsers.Chrome, Browsers.ChromiumEdge].includes(browserType)) { log.info( - `Chromedriver version: ${ - caps.get('chrome').chromedriverVersion - }, w3c=${isW3CEnabled}, codeCoverage=${collectCoverage}` + `${browserType}driver version: ${caps.get(browserType)[`${browserType}driverVersion`]}` ); } diff --git a/test/functional/services/remote/webdriver.ts b/test/functional/services/remote/webdriver.ts index 3bf5b865aa7ba..fc0b5bbb787c8 100644 --- a/test/functional/services/remote/webdriver.ts +++ b/test/functional/services/remote/webdriver.ts @@ -31,10 +31,12 @@ import { Builder, Capabilities, By, logging, until } from 'selenium-webdriver'; import chrome from 'selenium-webdriver/chrome'; import firefox from 'selenium-webdriver/firefox'; // @ts-ignore internal modules are not typed +import edge from 'selenium-webdriver/edge'; +import { installDriver } from 'ms-chromium-edge-driver'; +// @ts-ignore internal modules are not typed import { Executor } from 'selenium-webdriver/lib/http'; // @ts-ignore internal modules are not typed import { getLogger } from 'selenium-webdriver/lib/logging'; - import { pollForLogEntry$ } from './poll_for_log_entry'; import { createStdoutSocket } from './create_stdout_stream'; import { preventParallelCalls } from './prevent_parallel_calls'; @@ -63,6 +65,7 @@ Executor.prototype.execute = preventParallelCalls( ); let attemptCounter = 0; +let edgePaths: { driverPath: string | undefined; browserPath: string | undefined }; async function attemptToCreateCommand( log: ToolingLog, browserType: Browsers, @@ -74,6 +77,46 @@ async function attemptToCreateCommand( const buildDriverInstance = async () => { switch (browserType) { + case 'msedge': { + if (edgePaths && edgePaths.browserPath && edgePaths.driverPath) { + const edgeOptions = new edge.Options(); + if (headlessBrowser === '1') { + // @ts-ignore internal modules are not typed + edgeOptions.headless(); + } + // @ts-ignore internal modules are not typed + edgeOptions.setEdgeChromium(true); + // @ts-ignore internal modules are not typed + edgeOptions.setBinaryPath(edgePaths.browserPath); + const session = await new Builder() + .forBrowser('MicrosoftEdge') + .setEdgeOptions(edgeOptions) + .setEdgeService(new edge.ServiceBuilder(edgePaths.driverPath)) + .build(); + return { + session, + consoleLog$: pollForLogEntry$( + session, + logging.Type.BROWSER, + logPollingMs, + lifecycle.cleanup.after$ + ).pipe( + takeUntil(lifecycle.cleanup.after$), + map(({ message, level: { name: level } }) => ({ + message: message.replace(/\\n/g, '\n'), + level, + })) + ), + }; + } else { + throw new Error( + `Chromium Edge session requires browser or driver path to be defined: ${JSON.stringify( + edgePaths + )}` + ); + } + } + case 'chrome': { const chromeCapabilities = Capabilities.chrome(); const chromeOptions = [ @@ -265,6 +308,11 @@ export async function initWebDriver( log.verbose(entry.message); }); + // download Edge driver only in case of usage + if (browserType === Browsers.ChromiumEdge) { + edgePaths = await installDriver(); + } + return await Promise.race([ (async () => { await delay(2 * MINUTE); diff --git a/x-pack/test/functional/config.edge.js b/x-pack/test/functional/config.edge.js new file mode 100644 index 0000000000000..882fb6fea3686 --- /dev/null +++ b/x-pack/test/functional/config.edge.js @@ -0,0 +1,21 @@ +/* + * 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 default async function({ readConfigFile }) { + const chromeConfig = await readConfigFile(require.resolve('./config')); + + return { + ...chromeConfig.getAll(), + + browser: { + type: 'msedge', + }, + + junit: { + reportName: 'MS Chromium Edge XPack UI Functional Tests', + }, + }; +} diff --git a/yarn.lock b/yarn.lock index 77ab69c715573..3f04b2d26a013 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2499,6 +2499,11 @@ resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd" integrity sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow== +"@sindresorhus/is@^2.0.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-2.1.0.tgz#6ad4ca610f696098e92954ab431ff83bea0ce13f" + integrity sha512-lXKXfypKo644k4Da4yXkPCrwcvn6SlUW2X2zFbuflKHNjf0w9htru01bo26uMhleMXsDmnZ12eJLdrAZa9MANg== + "@sinonjs/commons@^1", "@sinonjs/commons@^1.3.0", "@sinonjs/commons@^1.4.0": version "1.6.0" resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.6.0.tgz#ec7670432ae9c8eb710400d112c201a362d83393" @@ -3398,6 +3403,13 @@ "@svgr/plugin-svgo" "^4.2.0" loader-utils "^1.2.3" +"@szmarczak/http-timer@^4.0.0": + version "4.0.5" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.5.tgz#bfbd50211e9dfa51ba07da58a14cdfd333205152" + integrity sha512-PyRA9sm1Yayuj5OIoJ1hGt2YISX45w9WcFbh6ddT0Z/0yaFxOtGLInr4jUfU1EAFVs0Yfyfev4RNwBlUaHdlDQ== + dependencies: + defer-to-connect "^2.0.0" + "@testim/chrome-version@^1.0.7": version "1.0.7" resolved "https://registry.yarnpkg.com/@testim/chrome-version/-/chrome-version-1.0.7.tgz#0cd915785ec4190f08a3a6acc9b61fc38fb5f1a9" @@ -3646,6 +3658,16 @@ resolved "https://registry.yarnpkg.com/@types/browserslist-useragent/-/browserslist-useragent-3.0.0.tgz#d425c9818182ce71ce53866798cee9c7d41d6e53" integrity sha512-ZBvKzg3yyWNYEkwxAzdmUzp27sFvw+1m080/+2lwrt+eltNefn1f4fnpMyrjOla31p8zLleCYqQXw+3EETfn0w== +"@types/cacheable-request@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.1.tgz#5d22f3dded1fd3a84c0bbeb5039a7419c2c91976" + integrity sha512-ykFq2zmBGOCbpIXtoVbz4SKY5QriWPh3AjyU4G74RYbtt5yOc5OfaY75ftjg7mikMOla1CTGpX3lLbuJh8DTrQ== + dependencies: + "@types/http-cache-semantics" "*" + "@types/keyv" "*" + "@types/node" "*" + "@types/responselike" "*" + "@types/caseless@*": version "0.12.2" resolved "https://registry.yarnpkg.com/@types/caseless/-/caseless-0.12.2.tgz#f65d3d6389e01eeb458bd54dc8f52b95a9463bc8" @@ -4015,6 +4037,11 @@ "@types/react" "*" hoist-non-react-statics "^3.3.0" +"@types/http-cache-semantics@*": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.0.tgz#9140779736aa2655635ee756e2467d787cfe8a2a" + integrity sha512-c3Xy026kOF7QOTn00hbIllV1dLR9hG9NkSrLQgCVs8NF6sBU+VGWjD3wLPhmh1TYAc7ugCFsvHYMN4VcBN1U1A== + "@types/indent-string@^3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@types/indent-string/-/indent-string-3.0.0.tgz#9ebb391ceda548926f5819ad16405349641b999f" @@ -4146,6 +4173,13 @@ dependencies: "@types/node" "*" +"@types/keyv@*": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.1.tgz#e45a45324fca9dab716ab1230ee249c9fb52cfa7" + integrity sha512-MPtoySlAZQ37VoLaPcTHCu1RWJ4llDkULYZIzOYxlhxBqYPB0RsRlmMU0R6tahtFe27mIdkHV+551ZWV4PLmVw== + dependencies: + "@types/node" "*" + "@types/license-checker@15.0.0": version "15.0.0" resolved "https://registry.yarnpkg.com/@types/license-checker/-/license-checker-15.0.0.tgz#685d69e2cf61ffd862320434601f51c85e28bba1" @@ -4617,6 +4651,13 @@ "@types/tough-cookie" "*" form-data "^2.5.0" +"@types/responselike@*": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.0.tgz#251f4fe7d154d2bad125abe1b429b23afd262e29" + integrity sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA== + dependencies: + "@types/node" "*" + "@types/retry@^0.12.0": version "0.12.0" resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d" @@ -4632,10 +4673,10 @@ resolved "https://registry.yarnpkg.com/@types/seedrandom/-/seedrandom-2.4.28.tgz#9ce8fa048c1e8c85cb71d7fe4d704e000226036f" integrity sha512-SMA+fUwULwK7sd/ZJicUztiPs8F1yCPwF3O23Z9uQ32ME5Ha0NmDK9+QTsYE4O2tHXChzXomSWWeIhCnoN1LqA== -"@types/selenium-webdriver@^4.0.5": - version "4.0.5" - resolved "https://registry.yarnpkg.com/@types/selenium-webdriver/-/selenium-webdriver-4.0.5.tgz#23041a4948c82daf2df9836e4d2358fec10d3e24" - integrity sha512-ma1aL1znI3ptEbSQgbywgadrRCJouPIACSfOl/bPwu/TPNSyyE/+o9jZ6+bpDVTtIdksZuVKpq4SR1ip3DRduw== +"@types/selenium-webdriver@4.0.9": + version "4.0.9" + resolved "https://registry.yarnpkg.com/@types/selenium-webdriver/-/selenium-webdriver-4.0.9.tgz#12621e55b2ef8f6c98bd17fe23fa720c6cba16bd" + integrity sha512-HopIwBE7GUXsscmt/J0DhnFXLSmO04AfxT6b8HAprknwka7pqEWquWDMXxCjd+NUHK9MkCe1SDKKsMiNmCItbQ== "@types/semver@^5.5.0": version "5.5.0" @@ -7358,13 +7399,18 @@ binaryextensions@2: resolved "https://registry.yarnpkg.com/binaryextensions/-/binaryextensions-2.1.1.tgz#3209a51ca4a4ad541a3b8d3d6a6d5b83a2485935" integrity sha512-XBaoWE9RW8pPdPQNibZsW2zh8TW6gcarXp1FZPwT8Uop8ScSNldJEWf2k9l3HeTqdrEwsOsFcq74RiJECW34yA== -bindings@^1.5.0: +bindings@1, bindings@^1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== dependencies: file-uri-to-path "1.0.0" +bindings@~1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.2.1.tgz#14ad6113812d2d37d72e67b4cacb4bb726505f11" + integrity sha1-FK1hE4EtLTfXLme0ystLtyZQXxE= + bit-twiddle@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/bit-twiddle/-/bit-twiddle-1.0.2.tgz#0c6c1fabe2b23d17173d9a61b7b7093eb9e1769e" @@ -7898,7 +7944,7 @@ buffer@^5.1.0, buffer@^5.2.0: base64-js "^1.0.2" ieee754 "^1.1.4" -builtin-modules@^1.0.0: +builtin-modules@^1.0.0, builtin-modules@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8= @@ -8045,6 +8091,13 @@ cache-loader@^4.1.0: neo-async "^2.6.1" schema-utils "^2.0.0" +cacheable-lookup@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-2.0.0.tgz#33b1e56f17507f5cf9bb46075112d65473fb7713" + integrity sha512-s2piO6LvA7xnL1AR03wuEdSx3BZT3tIJpZ56/lcJwzO/6DTJZlTs7X3lrvPxk6d1PlDe6PrVe2TjlUIZNFglAQ== + dependencies: + keyv "^4.0.0" + cacheable-request@^2.1.1: version "2.1.4" resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-2.1.4.tgz#0d808801b6342ad33c91df9d0b44dc09b91e5c3d" @@ -8058,6 +8111,19 @@ cacheable-request@^2.1.1: normalize-url "2.0.1" responselike "1.0.2" +cacheable-request@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.1.tgz#062031c2856232782ed694a257fa35da93942a58" + integrity sha512-lt0mJ6YAnsrBErpTMWeu5kl/tg9xMAWjavYTN6VQXM1A/teBITuNcccXsCxF0tDQQJf9DfAaX5O4e0zp0KlfZw== + dependencies: + clone-response "^1.0.2" + get-stream "^5.1.0" + http-cache-semantics "^4.0.0" + keyv "^4.0.0" + lowercase-keys "^2.0.0" + normalize-url "^4.1.0" + responselike "^2.0.0" + cachedir@2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/cachedir/-/cachedir-2.3.0.tgz#0c75892a052198f0b21c7c1804d8331edfcae0e8" @@ -8886,7 +8952,7 @@ clone-regexp@^1.0.0: is-regexp "^1.0.0" is-supported-regexp-flag "^1.0.0" -clone-response@1.0.2: +clone-response@1.0.2, clone-response@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws= @@ -9150,16 +9216,16 @@ commander@4.1.0: resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.0.tgz#545983a0603fe425bc672d66c9e3c89c42121a83" integrity sha512-NIQrwvv9V39FHgGFm36+U9SMQzbiHvU79k+iADraJTpmrFFfx7Ds0IvDoAdZsDrknlkRk14OYoWXb57uTh7/sw== +commander@^2.12.1, commander@^2.20.0, commander@^2.7.1: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + commander@^2.13.0, commander@^2.15.1, commander@^2.16.0, commander@^2.19.0: version "2.20.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ== -commander@^2.20.0, commander@^2.7.1: - version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - commander@^2.8.1: version "2.18.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.18.0.tgz#2bf063ddee7c7891176981a2cc798e5754bc6970" @@ -10575,7 +10641,7 @@ debug-fabulous@1.X: memoizee "0.4.X" object-assign "4.X" -debug@2.6.9, debug@^2.0.0, debug@^2.1.0, debug@^2.1.1, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.8, debug@^2.6.9: +debug@2, debug@2.6.9, debug@^2.0.0, debug@^2.1.0, debug@^2.1.1, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.8, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== @@ -10647,6 +10713,13 @@ decompress-response@^4.2.0: dependencies: mimic-response "^2.0.0" +decompress-response@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-5.0.0.tgz#7849396e80e3d1eba8cb2f75ef4930f76461cb0f" + integrity sha512-TLZWWybuxWgoW7Lykv+gq9xvzOsUjQ9tF09Tj6NSTYGMTCHNXzrPnD6Hi+TgZq19PyTAGH4Ll/NIM/eTGglnMw== + dependencies: + mimic-response "^2.0.0" + decompress-tar@^4.0.0, decompress-tar@^4.1.0, decompress-tar@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/decompress-tar/-/decompress-tar-4.1.1.tgz#718cbd3fcb16209716e70a26b84e7ba4592e5af1" @@ -10798,6 +10871,11 @@ defaults@^1.0.3: dependencies: clone "^1.0.2" +defer-to-connect@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.0.tgz#83d6b199db041593ac84d781b5222308ccf4c2c1" + integrity sha512-bYL2d05vOSf1JEZNx5vSAtPuBMkX8K9EUutg7zlKvTqKXHt7RhWJFbmd7qakVuf13i+IkGmp6FwSsONOf6VYIg== + define-properties@^1.1.2, define-properties@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" @@ -13239,6 +13317,17 @@ fetch-mock@^7.3.9: path-to-regexp "^2.2.1" whatwg-url "^6.5.0" +ffi@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/ffi/-/ffi-2.3.0.tgz#fa1a7b3d85c0fa8c83d96947a64b5192bc47f858" + integrity sha512-vkPA9Hf9CVuQ5HeMZykYvrZF2QNJ/iKGLkyDkisBnoOOFeFXZQhUPxBARPBIZMJVulvBI2R+jgofW03gyPpJcQ== + dependencies: + bindings "~1.2.0" + debug "2" + nan "2" + ref "1" + ref-struct "1" + figgy-pudding@^3.5.1: version "3.5.1" resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790" @@ -14716,6 +14805,27 @@ got@5.6.0: unzip-response "^1.0.0" url-parse-lax "^1.0.0" +got@^10.6.0: + version "10.6.0" + resolved "https://registry.yarnpkg.com/got/-/got-10.6.0.tgz#ac3876261a4d8e5fc4f81186f79955ce7b0501dc" + integrity sha512-3LIdJNTdCFbbJc+h/EH0V5lpNpbJ6Bfwykk21lcQvQsEcrzdi/ltCyQehFHLzJ/ka0UMH4Slg0hkYvAZN9qUDg== + dependencies: + "@sindresorhus/is" "^2.0.0" + "@szmarczak/http-timer" "^4.0.0" + "@types/cacheable-request" "^6.0.1" + cacheable-lookup "^2.0.0" + cacheable-request "^7.0.1" + decompress-response "^5.0.0" + duplexer3 "^0.1.4" + get-stream "^5.0.0" + lowercase-keys "^2.0.0" + mimic-response "^2.1.0" + p-cancelable "^2.0.0" + p-event "^4.0.0" + responselike "^2.0.0" + to-readable-stream "^2.0.0" + type-fest "^0.10.0" + got@^3.2.0: version "3.3.1" resolved "https://registry.yarnpkg.com/got/-/got-3.3.1.tgz#e5d0ed4af55fc3eef4d56007769d98192bcb2eca" @@ -15816,6 +15926,11 @@ http-cache-semantics@3.8.1: resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2" integrity sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w== +http-cache-semantics@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" + integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== + http-deceiver@^1.2.7: version "1.2.7" resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" @@ -16854,6 +16969,11 @@ is-generator-fn@^2.0.0: resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.0.0.tgz#038c31b774709641bda678b1f06a4e3227c10b3e" integrity sha512-elzyIdM7iKoFHzcrndIqjYomImhxrFRnGP3galODoII4TB9gI7mZ+FnlLQmmjf27SxHS2gKEeyhX5/+YRS6H9g== +is-generator-function@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.7.tgz#d2132e529bb0000a7f80794d4bdf5cd5e5813522" + integrity sha512-YZc5EwyO4f2kWCax7oegfuSr9mFz1ZvieNYBEjmukLxgXfBUbxAWGVF7GZf0zidYtoBl3WvC07YK0wT76a+Rtw== + is-glob@4.0.0, is-glob@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.0.tgz#9521c76845cc2610a85203ddf080a958c2ffabc0" @@ -18124,6 +18244,11 @@ json-buffer@3.0.0: resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= +json-buffer@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" + integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== + json-parse-better-errors@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.1.tgz#50183cd1b2d25275de069e9e71b467ac9eab973a" @@ -18359,7 +18484,7 @@ jsx-to-string@^1.4.0: json-stringify-pretty-compact "^1.0.1" react "^0.14.0" -jszip@^3.1.5: +jszip@^3.2.2: version "3.2.2" resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.2.2.tgz#b143816df7e106a9597a94c77493385adca5bd1d" integrity sha512-NmKajvAFQpbg3taXQXr/ccS2wcucR1AZ+NtyWp2Nq7HHVsXhcJFR8p0Baf32C2yVvBylFWVeKf+WI2AnvlPhpA== @@ -18535,6 +18660,13 @@ keyv@3.0.0: dependencies: json-buffer "3.0.0" +keyv@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.0.0.tgz#2d1dab694926b2d427e4c74804a10850be44c12f" + integrity sha512-U7ioE8AimvRVLfw4LffyOIRhL2xVgmE8T22L6i0BucSnBUyv4w+I7VN/zVZwRKHOI6ZRUcdMdWHQ8KSUvGpEog== + dependencies: + json-buffer "3.0.1" + killable@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892" @@ -19503,6 +19635,11 @@ lowercase-keys@^1.0.0: resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== +lowercase-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" + integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== + lowlight@~1.9.1: version "1.9.1" resolved "https://registry.yarnpkg.com/lowlight/-/lowlight-1.9.1.tgz#ed7c3dffc36f8c1f263735c0fe0c907847c11250" @@ -20163,6 +20300,11 @@ mimic-response@^2.0.0: resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-2.0.0.tgz#996a51c60adf12cb8a87d7fb8ef24c2f3d5ebb46" integrity sha512-8ilDoEapqA4uQ3TwS0jakGONKXVJqpy+RpM+3b7pLdOjghCrEiGp9SRkFbUHAmZW9vdnrENWHjaweIoTIJExSQ== +mimic-response@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-2.1.0.tgz#d13763d35f613d09ec37ebb30bac0469c0ee8f43" + integrity sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA== + mimos@4.x.x: version "4.0.0" resolved "https://registry.yarnpkg.com/mimos/-/mimos-4.0.0.tgz#76e3d27128431cb6482fd15b20475719ad626a5a" @@ -20591,6 +20733,19 @@ move-concurrently@^1.0.1: rimraf "^2.5.4" run-queue "^1.0.3" +ms-chromium-edge-driver@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/ms-chromium-edge-driver/-/ms-chromium-edge-driver-0.2.0.tgz#0e0c6fd9fd1d1d36db97b2b3d7e9d4ba4d2de456" + integrity sha512-RkDsBPnMLjRna7q4LlvtLb+CHPei9gZapnlxm3ayWKk3Ab6HmDsz/17xG2eyqkKX5UcKeo04YlLZ345tO7OolA== + dependencies: + extract-zip "^1.6.7" + got "^10.6.0" + lodash "4.17.15" + tslint "^6.1.0" + tslint-config-prettier "^1.18.0" + util "^0.12.2" + windows-registry "^0.1.5" + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" @@ -20703,7 +20858,7 @@ mute-stream@0.0.8: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== -nan@^2.12.1, nan@^2.13.2: +nan@2, nan@^2.12.1, nan@^2.13.2: version "2.14.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== @@ -21206,6 +21361,11 @@ normalize-url@^3.3.0: resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-3.3.0.tgz#b2e1c4dc4f7c6d57743df733a4f5978d18650559" integrity sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg== +normalize-url@^4.1.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129" + integrity sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ== + now-and-later@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/now-and-later/-/now-and-later-2.0.0.tgz#bc61cbb456d79cb32207ce47ca05136ff2e7d6ee" @@ -21891,6 +22051,11 @@ p-cancelable@^0.4.0: resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.4.1.tgz#35f363d67d52081c8d9585e37bcceb7e0bbcb2a0" integrity sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ== +p-cancelable@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.0.0.tgz#4a3740f5bdaf5ed5d7c3e34882c6fb5d6b266a6e" + integrity sha512-wvPXDmbMmu2ksjkB4Z3nZWTSkJEb9lqVdMaCKpZUGJG9TMiNp9XcbG3fn9fPKjem04fJMJnXoyFPk2FmgiaiNg== + p-defer@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" @@ -21903,7 +22068,7 @@ p-each-series@^1.0.0: dependencies: p-reduce "^1.0.0" -p-event@^4.1.0: +p-event@^4.0.0, p-event@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/p-event/-/p-event-4.1.0.tgz#e92bb866d7e8e5b732293b1c8269d38e9982bf8e" integrity sha512-4vAd06GCsgflX4wHN1JqrMzBh/8QZ4j+rzp0cd2scXRwuBEv+QR3wrVA5aLhWDLw4y2WgDKvzWF3CCLmVM1UgA== @@ -24952,6 +25117,31 @@ redux@^4.0.5: loose-envify "^1.4.0" symbol-observable "^1.2.0" +ref-struct@1, ref-struct@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/ref-struct/-/ref-struct-1.1.0.tgz#5d5ee65ad41cefc3a5c5feb40587261e479edc13" + integrity sha1-XV7mWtQc78Olxf60BYcmHkee3BM= + dependencies: + debug "2" + ref "1" + +ref-union@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ref-union/-/ref-union-1.0.1.tgz#3a2397f862f1e75171d687268f43b3f17729f120" + integrity sha1-OiOX+GLx51Fx1ocmj0Oz8Xcp8SA= + dependencies: + debug "2" + ref "1" + +ref@1, ref@^1.2.0: + version "1.3.5" + resolved "https://registry.yarnpkg.com/ref/-/ref-1.3.5.tgz#0e33f080cdb94a3d95312b2b3b1fd0f82044ca0f" + integrity sha512-2cBCniTtxcGUjDpvFfVpw323a83/0RLSGJJY5l5lcomZWhYpU2cuLdsvYqMixvsdLJ9+sTdzEkju8J8ZHDM2nA== + dependencies: + bindings "1" + debug "2" + nan "2" + reflect.ownkeys@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/reflect.ownkeys/-/reflect.ownkeys-0.2.0.tgz#749aceec7f3fdf8b63f927a04809e90c5c0b3460" @@ -25691,6 +25881,13 @@ responselike@1.0.2: dependencies: lowercase-keys "^1.0.0" +responselike@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.0.tgz#26391bcc3174f750f9a79eacc40a12a5c42d7723" + integrity sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw== + dependencies: + lowercase-keys "^2.0.0" + restore-cursor@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541" @@ -26249,15 +26446,14 @@ select@^1.1.2: resolved "https://registry.yarnpkg.com/select/-/select-1.1.2.tgz#0e7350acdec80b1108528786ec1d4418d11b396d" integrity sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0= -selenium-webdriver@^4.0.0-alpha.5: - version "4.0.0-alpha.5" - resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-4.0.0-alpha.5.tgz#e4683b3dbf827d70df09a7e43bf02ebad20fa7c1" - integrity sha512-hktl3DSrhzM59yLhWzDGHIX9o56DvA+cVK7Dw6FcJR6qQ4CGzkaHeXQPcdrslkWMTeq0Ci9AmCxq0EMOvm2Rkg== +selenium-webdriver@^4.0.0-alpha.7: + version "4.0.0-alpha.7" + resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-4.0.0-alpha.7.tgz#e3879d8457fd7ad8e4424094b7dc0540d99e6797" + integrity sha512-D4qnTsyTr91jT8f7MfN+OwY0IlU5+5FmlO5xlgRUV6hDEV8JyYx2NerdTEqDDkNq7RZDYc4VoPALk8l578RBHw== dependencies: - jszip "^3.1.5" - rimraf "^2.6.3" + jszip "^3.2.2" + rimraf "^2.7.1" tmp "0.0.30" - xml2js "^0.4.19" selfsigned@^1.10.7: version "1.10.7" @@ -28648,6 +28844,11 @@ to-object-path@^0.3.0: dependencies: kind-of "^3.0.2" +to-readable-stream@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-2.1.0.tgz#82880316121bea662cdc226adb30addb50cb06e8" + integrity sha512-o3Qa6DGg1CEXshSdvWNX2sN4QHqg03SPq7U6jPXRahlQdl5dK8oXjkU/2/sGrnOZKeGV1zLSO8qPwyKklPPE7w== + to-regex-range@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" @@ -28927,6 +29128,37 @@ tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.2, tslib@^1.9.3: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ== +tslint-config-prettier@^1.18.0: + version "1.18.0" + resolved "https://registry.yarnpkg.com/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz#75f140bde947d35d8f0d238e0ebf809d64592c37" + integrity sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg== + +tslint@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/tslint/-/tslint-6.1.0.tgz#c6c611b8ba0eed1549bf5a59ba05a7732133d851" + integrity sha512-fXjYd/61vU6da04E505OZQGb2VCN2Mq3doeWcOIryuG+eqdmFUXTYVwdhnbEu2k46LNLgUYt9bI5icQze/j0bQ== + dependencies: + "@babel/code-frame" "^7.0.0" + builtin-modules "^1.1.1" + chalk "^2.3.0" + commander "^2.12.1" + diff "^4.0.1" + glob "^7.1.1" + js-yaml "^3.13.1" + minimatch "^3.0.4" + mkdirp "^0.5.1" + resolve "^1.3.2" + semver "^5.3.0" + tslib "^1.10.0" + tsutils "^2.29.0" + +tsutils@^2.29.0: + version "2.29.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.29.0.tgz#32b488501467acbedd4b85498673a0812aca0b99" + integrity sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA== + dependencies: + tslib "^1.8.1" + tsutils@^3.17.1: version "3.17.1" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759" @@ -29431,6 +29663,11 @@ type-detect@^1.0.0: resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-1.0.0.tgz#762217cc06db258ec48908a1298e8b95121e8ea2" integrity sha1-diIXzAbbJY7EiQihKY6LlRIejqI= +type-fest@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.10.0.tgz#7f06b2b9fbfc581068d1341ffabd0349ceafc642" + integrity sha512-EUV9jo4sffrwlg8s0zDhP0T2WD3pru5Xi0+HTE3zTUmBaZNhfkite9PdSJwdXLwPVW0jnAHT56pZHIOYckPEiw== + type-fest@^0.3.0, type-fest@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.3.1.tgz#63d00d204e059474fe5e1b7c011112bbd1dc29e1" @@ -30121,6 +30358,16 @@ util@^0.11.0: dependencies: inherits "2.0.3" +util@^0.12.2: + version "0.12.2" + resolved "https://registry.yarnpkg.com/util/-/util-0.12.2.tgz#54adb634c9e7c748707af2bf5a8c7ab640cbba2b" + integrity sha512-XE+MkWQvglYa+IOfBt5UFG93EmncEMP23UqpgDvVZVFBPxwmkK10QRp6pgU4xICPnWRf/t0zPv4noYSUq9gqUQ== + dependencies: + inherits "^2.0.3" + is-arguments "^1.0.4" + is-generator-function "^1.0.7" + safe-buffer "^5.1.2" + utila@^0.4.0, utila@~0.4: version "0.4.0" resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c" @@ -31277,6 +31524,17 @@ window-size@^0.2.0: resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.2.0.tgz#b4315bb4214a3d7058ebeee892e13fa24d98b075" integrity sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU= +windows-registry@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/windows-registry/-/windows-registry-0.1.5.tgz#92c25c960884b0d215e69395f52d8dfaa0ba4ad0" + integrity sha512-gMN3ets1fbdP+TApEbbX2TIfBK3MIH5+p9GMvIFS3CNLr7U0Khe5mRj/T5zvwo/pKdhJgDrCLYyaNSs7HYiBCw== + dependencies: + debug "^2.2.0" + ffi "^2.0.0" + ref "^1.2.0" + ref-struct "^1.0.2" + ref-union "^1.0.0" + windows-release@^3.1.0: version "3.2.0" resolved "https://registry.yarnpkg.com/windows-release/-/windows-release-3.2.0.tgz#8122dad5afc303d833422380680a79cdfa91785f" @@ -31575,14 +31833,6 @@ xml-parse-from-string@^1.0.0: resolved "https://registry.yarnpkg.com/xml-parse-from-string/-/xml-parse-from-string-1.0.1.tgz#a9029e929d3dbcded169f3c6e28238d95a5d5a28" integrity sha1-qQKekp09vN7RafPG4oI42VpdWig= -xml2js@^0.4.19, xml2js@^0.4.5: - version "0.4.19" - resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.19.tgz#686c20f213209e94abf0d1bcf1efaa291c7827a7" - integrity sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q== - dependencies: - sax ">=0.6.0" - xmlbuilder "~9.0.1" - xml2js@^0.4.22: version "0.4.22" resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.22.tgz#4fa2d846ec803237de86f30aa9b5f70b6600de02" @@ -31592,6 +31842,14 @@ xml2js@^0.4.22: util.promisify "~1.0.0" xmlbuilder "~11.0.0" +xml2js@^0.4.5: + version "0.4.19" + resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.19.tgz#686c20f213209e94abf0d1bcf1efaa291c7827a7" + integrity sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q== + dependencies: + sax ">=0.6.0" + xmlbuilder "~9.0.1" + xml@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/xml/-/xml-1.0.1.tgz#78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5" From e3bd04fcb078a8fd01d315bbde68781bdd8a3cfd Mon Sep 17 00:00:00 2001 From: Gidi Meir Morris Date: Wed, 8 Apr 2020 22:36:33 +0100 Subject: [PATCH 34/40] [Alerting] Displays warning when a permanent encryption key is missing and hides alerting UI appropriately (#62772) Removes the Security flyout and instead replaces the Alerting List, Connectors List and Alert Flyout with suitable messaging. Verifies that a permanent Encryption Key has been configured and if it hasn't displays a suitable warning in place, or along side the TLS warning, as needed. --- x-pack/plugins/alerting/common/index.ts | 1 + x-pack/plugins/alerting/server/plugin.ts | 2 +- .../alerting/server/routes/health.test.ts | 58 +++++- .../plugins/alerting/server/routes/health.ts | 8 +- .../translations/translations/ja-JP.json | 17 +- .../translations/translations/zh-CN.json | 17 +- .../alert_action_security_call_out.test.tsx | 78 ------- .../alert_action_security_call_out.tsx | 78 ------- .../application/components/health_check.scss | 13 ++ .../components/health_check.test.tsx | 131 ++++++++++++ .../application/components/health_check.tsx | 197 ++++++++++++++++++ .../prompts/empty_connectors_prompt.scss | 3 + .../prompts/empty_connectors_prompt.tsx | 55 +++++ .../components/prompts/empty_prompt.tsx | 47 +++++ .../components/security_call_out.test.tsx | 72 ------- .../components/security_call_out.tsx | 75 ------- .../public/application/home.tsx | 25 ++- .../components/actions_connectors_list.scss | 4 - .../components/actions_connectors_list.tsx | 53 +---- .../sections/alert_form/alert_add.test.tsx | 5 +- .../sections/alert_form/alert_add.tsx | 104 +++++---- .../sections/alert_form/alert_edit.test.tsx | 5 +- .../sections/alert_form/alert_edit.tsx | 134 ++++++------ .../alerts_list/components/alerts_list.tsx | 42 +--- 24 files changed, 662 insertions(+), 562 deletions(-) delete mode 100644 x-pack/plugins/triggers_actions_ui/public/application/components/alert_action_security_call_out.test.tsx delete mode 100644 x-pack/plugins/triggers_actions_ui/public/application/components/alert_action_security_call_out.tsx create mode 100644 x-pack/plugins/triggers_actions_ui/public/application/components/health_check.scss create mode 100644 x-pack/plugins/triggers_actions_ui/public/application/components/health_check.test.tsx create mode 100644 x-pack/plugins/triggers_actions_ui/public/application/components/health_check.tsx create mode 100644 x-pack/plugins/triggers_actions_ui/public/application/components/prompts/empty_connectors_prompt.scss create mode 100644 x-pack/plugins/triggers_actions_ui/public/application/components/prompts/empty_connectors_prompt.tsx create mode 100644 x-pack/plugins/triggers_actions_ui/public/application/components/prompts/empty_prompt.tsx delete mode 100644 x-pack/plugins/triggers_actions_ui/public/application/components/security_call_out.test.tsx delete mode 100644 x-pack/plugins/triggers_actions_ui/public/application/components/security_call_out.tsx diff --git a/x-pack/plugins/alerting/common/index.ts b/x-pack/plugins/alerting/common/index.ts index 9d4ea69a63609..2574e73dd4f9a 100644 --- a/x-pack/plugins/alerting/common/index.ts +++ b/x-pack/plugins/alerting/common/index.ts @@ -17,6 +17,7 @@ export interface ActionGroup { export interface AlertingFrameworkHealth { isSufficientlySecure: boolean; + hasPermanentEncryptionKey: boolean; } export const BASE_ALERT_API_PATH = '/api/alert'; diff --git a/x-pack/plugins/alerting/server/plugin.ts b/x-pack/plugins/alerting/server/plugin.ts index 172a106226345..fdca6c0a9b503 100644 --- a/x-pack/plugins/alerting/server/plugin.ts +++ b/x-pack/plugins/alerting/server/plugin.ts @@ -190,7 +190,7 @@ export class AlertingPlugin { unmuteAllAlertRoute(router, this.licenseState); muteAlertInstanceRoute(router, this.licenseState); unmuteAlertInstanceRoute(router, this.licenseState); - healthRoute(router, this.licenseState); + healthRoute(router, this.licenseState, plugins.encryptedSavedObjects); return { registerType: alertTypeRegistry.register.bind(alertTypeRegistry), diff --git a/x-pack/plugins/alerting/server/routes/health.test.ts b/x-pack/plugins/alerting/server/routes/health.test.ts index 9efe020bc10c4..42c83a7c04deb 100644 --- a/x-pack/plugins/alerting/server/routes/health.test.ts +++ b/x-pack/plugins/alerting/server/routes/health.test.ts @@ -10,6 +10,7 @@ import { mockHandlerArguments } from './_mock_handler_arguments'; import { elasticsearchServiceMock } from '../../../../../src/core/server/mocks'; import { verifyApiAccess } from '../lib/license_api_access'; import { mockLicenseState } from '../lib/license_state.mock'; +import { encryptedSavedObjectsMock } from '../../../encrypted_saved_objects/server/mocks'; jest.mock('../lib/license_api_access.ts', () => ({ verifyApiAccess: jest.fn(), @@ -24,7 +25,9 @@ describe('healthRoute', () => { const router: RouterMock = mockRouter.create(); const licenseState = mockLicenseState(); - healthRoute(router, licenseState); + const encryptedSavedObjects = encryptedSavedObjectsMock.createSetup(); + encryptedSavedObjects.usingEphemeralEncryptionKey = false; + healthRoute(router, licenseState, encryptedSavedObjects); const [config] = router.get.mock.calls[0]; @@ -35,7 +38,9 @@ describe('healthRoute', () => { const router: RouterMock = mockRouter.create(); const licenseState = mockLicenseState(); - healthRoute(router, licenseState); + const encryptedSavedObjects = encryptedSavedObjectsMock.createSetup(); + encryptedSavedObjects.usingEphemeralEncryptionKey = false; + healthRoute(router, licenseState, encryptedSavedObjects); const [, handler] = router.get.mock.calls[0]; const elasticsearch = elasticsearchServiceMock.createSetup(); @@ -58,11 +63,37 @@ describe('healthRoute', () => { `); }); + it('evaluates whether Encrypted Saved Objects is using an ephemeral encryption key', async () => { + const router: RouterMock = mockRouter.create(); + + const licenseState = mockLicenseState(); + const encryptedSavedObjects = encryptedSavedObjectsMock.createSetup(); + encryptedSavedObjects.usingEphemeralEncryptionKey = true; + healthRoute(router, licenseState, encryptedSavedObjects); + const [, handler] = router.get.mock.calls[0]; + + const elasticsearch = elasticsearchServiceMock.createSetup(); + elasticsearch.adminClient.callAsInternalUser.mockReturnValue(Promise.resolve({})); + + const [context, req, res] = mockHandlerArguments({ elasticsearch }, {}, ['ok']); + + expect(await handler(context, req, res)).toMatchInlineSnapshot(` + Object { + "body": Object { + "hasPermanentEncryptionKey": false, + "isSufficientlySecure": true, + }, + } + `); + }); + it('evaluates missing security info from the usage api to mean that the security plugin is disbled', async () => { const router: RouterMock = mockRouter.create(); const licenseState = mockLicenseState(); - healthRoute(router, licenseState); + const encryptedSavedObjects = encryptedSavedObjectsMock.createSetup(); + encryptedSavedObjects.usingEphemeralEncryptionKey = false; + healthRoute(router, licenseState, encryptedSavedObjects); const [, handler] = router.get.mock.calls[0]; const elasticsearch = elasticsearchServiceMock.createSetup(); @@ -73,6 +104,7 @@ describe('healthRoute', () => { expect(await handler(context, req, res)).toMatchInlineSnapshot(` Object { "body": Object { + "hasPermanentEncryptionKey": true, "isSufficientlySecure": true, }, } @@ -83,7 +115,9 @@ describe('healthRoute', () => { const router: RouterMock = mockRouter.create(); const licenseState = mockLicenseState(); - healthRoute(router, licenseState); + const encryptedSavedObjects = encryptedSavedObjectsMock.createSetup(); + encryptedSavedObjects.usingEphemeralEncryptionKey = false; + healthRoute(router, licenseState, encryptedSavedObjects); const [, handler] = router.get.mock.calls[0]; const elasticsearch = elasticsearchServiceMock.createSetup(); @@ -94,6 +128,7 @@ describe('healthRoute', () => { expect(await handler(context, req, res)).toMatchInlineSnapshot(` Object { "body": Object { + "hasPermanentEncryptionKey": true, "isSufficientlySecure": true, }, } @@ -104,7 +139,9 @@ describe('healthRoute', () => { const router: RouterMock = mockRouter.create(); const licenseState = mockLicenseState(); - healthRoute(router, licenseState); + const encryptedSavedObjects = encryptedSavedObjectsMock.createSetup(); + encryptedSavedObjects.usingEphemeralEncryptionKey = false; + healthRoute(router, licenseState, encryptedSavedObjects); const [, handler] = router.get.mock.calls[0]; const elasticsearch = elasticsearchServiceMock.createSetup(); @@ -117,6 +154,7 @@ describe('healthRoute', () => { expect(await handler(context, req, res)).toMatchInlineSnapshot(` Object { "body": Object { + "hasPermanentEncryptionKey": true, "isSufficientlySecure": false, }, } @@ -127,7 +165,9 @@ describe('healthRoute', () => { const router: RouterMock = mockRouter.create(); const licenseState = mockLicenseState(); - healthRoute(router, licenseState); + const encryptedSavedObjects = encryptedSavedObjectsMock.createSetup(); + encryptedSavedObjects.usingEphemeralEncryptionKey = false; + healthRoute(router, licenseState, encryptedSavedObjects); const [, handler] = router.get.mock.calls[0]; const elasticsearch = elasticsearchServiceMock.createSetup(); @@ -140,6 +180,7 @@ describe('healthRoute', () => { expect(await handler(context, req, res)).toMatchInlineSnapshot(` Object { "body": Object { + "hasPermanentEncryptionKey": true, "isSufficientlySecure": false, }, } @@ -150,7 +191,9 @@ describe('healthRoute', () => { const router: RouterMock = mockRouter.create(); const licenseState = mockLicenseState(); - healthRoute(router, licenseState); + const encryptedSavedObjects = encryptedSavedObjectsMock.createSetup(); + encryptedSavedObjects.usingEphemeralEncryptionKey = false; + healthRoute(router, licenseState, encryptedSavedObjects); const [, handler] = router.get.mock.calls[0]; const elasticsearch = elasticsearchServiceMock.createSetup(); @@ -163,6 +206,7 @@ describe('healthRoute', () => { expect(await handler(context, req, res)).toMatchInlineSnapshot(` Object { "body": Object { + "hasPermanentEncryptionKey": true, "isSufficientlySecure": true, }, } diff --git a/x-pack/plugins/alerting/server/routes/health.ts b/x-pack/plugins/alerting/server/routes/health.ts index 29c2f3c5730f4..fa2358a1f181c 100644 --- a/x-pack/plugins/alerting/server/routes/health.ts +++ b/x-pack/plugins/alerting/server/routes/health.ts @@ -14,6 +14,7 @@ import { import { LicenseState } from '../lib/license_state'; import { verifyApiAccess } from '../lib/license_api_access'; import { AlertingFrameworkHealth } from '../types'; +import { EncryptedSavedObjectsPluginSetup } from '../../../encrypted_saved_objects/server'; interface XPackUsageSecurity { security?: { @@ -26,7 +27,11 @@ interface XPackUsageSecurity { }; } -export function healthRoute(router: IRouter, licenseState: LicenseState) { +export function healthRoute( + router: IRouter, + licenseState: LicenseState, + encryptedSavedObjects: EncryptedSavedObjectsPluginSetup +) { router.get( { path: '/api/alert/_health', @@ -54,6 +59,7 @@ export function healthRoute(router: IRouter, licenseState: LicenseState) { const frameworkHealth: AlertingFrameworkHealth = { isSufficientlySecure: !isSecurityEnabled || (isSecurityEnabled && isTLSEnabled), + hasPermanentEncryptionKey: !encryptedSavedObjects.usingEphemeralEncryptionKey, }; return res.ok({ diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 00ac5b77d00f3..e63e1c8ad2c91 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -15864,8 +15864,6 @@ "xpack.triggersActionsUI.common.expressionItems.threshold.andLabel": "AND", "xpack.triggersActionsUI.common.expressionItems.threshold.descriptionLabel": "タイミング", "xpack.triggersActionsUI.common.expressionItems.threshold.popoverTitle": "タイミング", - "xpack.triggersActionsUI.components.alertActionSecurityCallOut.enableTlsCta": "TLS を有効にする", - "xpack.triggersActionsUI.components.alertActionSecurityCallOut.tlsDisabledTitle": "アラート {action} を実行するには Elasticsearch と Kibana の間に TLS が必要です。", "xpack.triggersActionsUI.components.builtinActionTypes.emailAction.actionTypeTitle": "メールに送信", "xpack.triggersActionsUI.components.builtinActionTypes.emailAction.addVariablePopoverButton": "変数を追加", "xpack.triggersActionsUI.components.builtinActionTypes.emailAction.selectMessageText": "サーバーからメールを送信します。", @@ -15960,9 +15958,6 @@ "xpack.triggersActionsUI.components.builtinActionTypes.webhookAction.viewHeadersSwitch": "HTTP ヘッダーを追加", "xpack.triggersActionsUI.components.deleteSelectedIdsErrorNotification.descriptionText": "{numErrors, number} {numErrors, plural, one {{singleTitle}} other {{multipleTitle}}}を削除できませんでした", "xpack.triggersActionsUI.components.deleteSelectedIdsSuccessNotification.descriptionText": "{numSuccesses, number} {numSuccesses, plural, one {{singleTitle}} other {{multipleTitle}}}を削除しました", - "xpack.triggersActionsUI.components.securityCallOut.enableTlsCta": "TLS を有効にする", - "xpack.triggersActionsUI.components.securityCallOut.tlsDisabledDescription": "アラートは API キー に依存し、キーを使用するには Elasticsearch と Kibana の間に TLS が必要です。", - "xpack.triggersActionsUI.components.securityCallOut.tlsDisabledTitle": "トランスポートレイヤーセキュリティを有効にする", "xpack.triggersActionsUI.connectors.breadcrumbTitle": "コネクター", "xpack.triggersActionsUI.deleteSelectedIdsConfirmModal.cancelButtonLabel": "キャンセル", "xpack.triggersActionsUI.deleteSelectedIdsConfirmModal.deleteButtonLabel": "{numIdsToDelete, plural, one {{singleTitle}} other {# {multipleTitle}}}を削除 ", @@ -15986,8 +15981,8 @@ "xpack.triggersActionsUI.sections.actionConnectorForm.error.requiredNameText": "名前が必要です。", "xpack.triggersActionsUI.sections.actionForm.getMoreActionsTitle": "さらにアクションを表示", "xpack.triggersActionsUI.sections.actionsConnectorsList.addActionButtonLabel": "コネクターを作成", - "xpack.triggersActionsUI.sections.actionsConnectorsList.addActionEmptyBody": "Kibana でトリガーできるメール、Slack, Elasticsearch、およびサードパーティサービスを構成します。", - "xpack.triggersActionsUI.sections.actionsConnectorsList.addActionEmptyTitle": "初めてのコネクターを作成する", + "xpack.triggersActionsUI.components.emptyConnectorsPrompt.addActionEmptyBody": "Kibana でトリガーできるメール、Slack, Elasticsearch、およびサードパーティサービスを構成します。", + "xpack.triggersActionsUI.components.emptyConnectorsPrompt.addActionEmptyTitle": "初めてのコネクターを作成する", "xpack.triggersActionsUI.sections.actionsConnectorsList.buttons.deleteDisabledTitle": "コネクターを削除できません", "xpack.triggersActionsUI.sections.actionsConnectorsList.buttons.deleteLabel": "{count} 件を削除", "xpack.triggersActionsUI.sections.actionsConnectorsList.connectorsListTable.columns.actions.deleteActionDescription": "このコネクターを削除", @@ -16037,7 +16032,6 @@ "xpack.triggersActionsUI.sections.alertAdd.saveButtonLabel": "保存", "xpack.triggersActionsUI.sections.alertAdd.saveErrorNotificationText": "アラートを作成できません。", "xpack.triggersActionsUI.sections.alertAdd.saveSuccessNotificationText": "「{alertName}」 を保存しました", - "xpack.triggersActionsUI.sections.alertAdd.securityCalloutAction": "作成", "xpack.triggersActionsUI.sections.alertAdd.selectIndex": "インデックスを選択してください。", "xpack.triggersActionsUI.sections.alertAdd.threshold.closeIndexPopoverLabel": "閉じる", "xpack.triggersActionsUI.sections.alertAdd.threshold.fixErrorInExpressionBelowValidationMessage": "下の表現のエラーを修正してください。", @@ -16074,7 +16068,6 @@ "xpack.triggersActionsUI.sections.alertEdit.saveButtonLabel": "保存", "xpack.triggersActionsUI.sections.alertEdit.saveErrorNotificationText": "アラートを更新できません。", "xpack.triggersActionsUI.sections.alertEdit.saveSuccessNotificationText": "「{alertName}」 を更新しました", - "xpack.triggersActionsUI.sections.alertEdit.securityCalloutAction": "編集中", "xpack.triggersActionsUI.sections.alertForm.accordion.deleteIconAriaLabel": "削除", "xpack.triggersActionsUI.sections.alertForm.actionDisabledTitle": "このアクションは無効です", "xpack.triggersActionsUI.sections.alertForm.actionIdLabel": "{connectorInstance} コネクター", @@ -16126,9 +16119,9 @@ "xpack.triggersActionsUI.sections.alertsList.collapsedItemActons.enableTitle": "有効にする", "xpack.triggersActionsUI.sections.alertsList.collapsedItemActons.muteTitle": "ミュート", "xpack.triggersActionsUI.sections.alertsList.collapsedItemActons.popoverButtonTitle": "アクション", - "xpack.triggersActionsUI.sections.alertsList.emptyButton": "アラートの作成", - "xpack.triggersActionsUI.sections.alertsList.emptyDesc": "トリガーが起きたときにメール、Slack、または別のコネクターを通してアラートを受信します。", - "xpack.triggersActionsUI.sections.alertsList.emptyTitle": "初めてのアラートを作成する", + "xpack.triggersActionsUI.components.emptyPrompt.emptyButton": "アラートの作成", + "xpack.triggersActionsUI.components.emptyPrompt.emptyDesc": "トリガーが起きたときにメール、Slack、または別のコネクターを通してアラートを受信します。", + "xpack.triggersActionsUI.components.emptyPrompt.emptyTitle": "初めてのアラートを作成する", "xpack.triggersActionsUI.sections.alertsList.multipleTitle": "アラート", "xpack.triggersActionsUI.sections.alertsList.searchPlaceholderTitle": "検索", "xpack.triggersActionsUI.sections.alertsList.singleTitle": "アラート", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index f6d84431bef7f..cc75ceb988d97 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -15868,8 +15868,6 @@ "xpack.triggersActionsUI.common.expressionItems.threshold.andLabel": "且", "xpack.triggersActionsUI.common.expressionItems.threshold.descriptionLabel": "当", "xpack.triggersActionsUI.common.expressionItems.threshold.popoverTitle": "当", - "xpack.triggersActionsUI.components.alertActionSecurityCallOut.enableTlsCta": "启用 TLS", - "xpack.triggersActionsUI.components.alertActionSecurityCallOut.tlsDisabledTitle": "告警 {action} 在 Elasticsearch 和 Kibana 之间需要 TLS。", "xpack.triggersActionsUI.components.builtinActionTypes.emailAction.actionTypeTitle": "发送到电子邮件", "xpack.triggersActionsUI.components.builtinActionTypes.emailAction.addVariablePopoverButton": "添加变量", "xpack.triggersActionsUI.components.builtinActionTypes.emailAction.selectMessageText": "从您的服务器发送电子邮件。", @@ -15964,9 +15962,6 @@ "xpack.triggersActionsUI.components.builtinActionTypes.webhookAction.viewHeadersSwitch": "添加 HTTP 标头", "xpack.triggersActionsUI.components.deleteSelectedIdsErrorNotification.descriptionText": "无法删除 {numErrors, number} 个{numErrors, plural, one {{singleTitle}} other {{multipleTitle}}}", "xpack.triggersActionsUI.components.deleteSelectedIdsSuccessNotification.descriptionText": "已删除 {numSuccesses, number} 个{numSuccesses, plural, one {{singleTitle}} other {{multipleTitle}}}", - "xpack.triggersActionsUI.components.securityCallOut.enableTlsCta": "启用 TLS", - "xpack.triggersActionsUI.components.securityCallOut.tlsDisabledDescription": "Alerting 依赖于在 Elasticsearch 和 Kibana 之间需要 TLS 的 API 密钥。", - "xpack.triggersActionsUI.components.securityCallOut.tlsDisabledTitle": "启用传输层安全", "xpack.triggersActionsUI.connectors.breadcrumbTitle": "连接器", "xpack.triggersActionsUI.deleteSelectedIdsConfirmModal.cancelButtonLabel": "取消", "xpack.triggersActionsUI.deleteSelectedIdsConfirmModal.deleteButtonLabel": "删除{numIdsToDelete, plural, one {{singleTitle}} other { # 个{multipleTitle}}} ", @@ -15991,8 +15986,8 @@ "xpack.triggersActionsUI.sections.actionConnectorForm.error.requiredNameText": "名称必填。", "xpack.triggersActionsUI.sections.actionForm.getMoreActionsTitle": "获取更多的操作", "xpack.triggersActionsUI.sections.actionsConnectorsList.addActionButtonLabel": "创建连接器", - "xpack.triggersActionsUI.sections.actionsConnectorsList.addActionEmptyBody": "配置电子邮件、Slack、Elasticsearch 和 Kibana 可以触发的第三方服务。", - "xpack.triggersActionsUI.sections.actionsConnectorsList.addActionEmptyTitle": "创建您的首个连接器", + "xpack.triggersActionsUI.components.emptyConnectorsPrompt.addActionEmptyBody": "配置电子邮件、Slack、Elasticsearch 和 Kibana 可以触发的第三方服务。", + "xpack.triggersActionsUI.components.emptyConnectorsPrompt.addActionEmptyTitle": "创建您的首个连接器", "xpack.triggersActionsUI.sections.actionsConnectorsList.buttons.deleteDisabledTitle": "无法删除连接器", "xpack.triggersActionsUI.sections.actionsConnectorsList.buttons.deleteLabel": "删除 {count} 个", "xpack.triggersActionsUI.sections.actionsConnectorsList.connectorsListTable.columns.actions.deleteActionDescription": "删除此连接器", @@ -16042,7 +16037,6 @@ "xpack.triggersActionsUI.sections.alertAdd.saveButtonLabel": "保存", "xpack.triggersActionsUI.sections.alertAdd.saveErrorNotificationText": "无法创建告警。", "xpack.triggersActionsUI.sections.alertAdd.saveSuccessNotificationText": "已保存“{alertName}”", - "xpack.triggersActionsUI.sections.alertAdd.securityCalloutAction": "创建", "xpack.triggersActionsUI.sections.alertAdd.selectIndex": "选择索引。", "xpack.triggersActionsUI.sections.alertAdd.threshold.closeIndexPopoverLabel": "关闭", "xpack.triggersActionsUI.sections.alertAdd.threshold.fixErrorInExpressionBelowValidationMessage": "表达式包含错误。", @@ -16079,7 +16073,6 @@ "xpack.triggersActionsUI.sections.alertEdit.saveButtonLabel": "保存", "xpack.triggersActionsUI.sections.alertEdit.saveErrorNotificationText": "无法更新告警。", "xpack.triggersActionsUI.sections.alertEdit.saveSuccessNotificationText": "已更新“{alertName}”", - "xpack.triggersActionsUI.sections.alertEdit.securityCalloutAction": "正在编辑", "xpack.triggersActionsUI.sections.alertForm.accordion.deleteIconAriaLabel": "删除", "xpack.triggersActionsUI.sections.alertForm.actionDisabledTitle": "此操作已禁用", "xpack.triggersActionsUI.sections.alertForm.actionIdLabel": "{connectorInstance} 连接器", @@ -16131,9 +16124,9 @@ "xpack.triggersActionsUI.sections.alertsList.collapsedItemActons.enableTitle": "启用", "xpack.triggersActionsUI.sections.alertsList.collapsedItemActons.muteTitle": "静音", "xpack.triggersActionsUI.sections.alertsList.collapsedItemActons.popoverButtonTitle": "操作", - "xpack.triggersActionsUI.sections.alertsList.emptyButton": "创建告警", - "xpack.triggersActionsUI.sections.alertsList.emptyDesc": "触发条件满足时通过电子邮件、Slack 或其他连接器接收告警。", - "xpack.triggersActionsUI.sections.alertsList.emptyTitle": "创建您的首个告警", + "xpack.triggersActionsUI.components.emptyPrompt.emptyButton": "创建告警", + "xpack.triggersActionsUI.components.emptyPrompt.emptyDesc": "触发条件满足时通过电子邮件、Slack 或其他连接器接收告警。", + "xpack.triggersActionsUI.components.emptyPrompt.emptyTitle": "创建您的首个告警", "xpack.triggersActionsUI.sections.alertsList.multipleTitle": "告警", "xpack.triggersActionsUI.sections.alertsList.searchPlaceholderTitle": "搜索", "xpack.triggersActionsUI.sections.alertsList.singleTitle": "告警", diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/alert_action_security_call_out.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/alert_action_security_call_out.test.tsx deleted file mode 100644 index 85699cfbd750f..0000000000000 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/alert_action_security_call_out.test.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 React, { Fragment } from 'react'; -import { shallow, ShallowWrapper } from 'enzyme'; -import { AlertActionSecurityCallOut } from './alert_action_security_call_out'; - -import { EuiCallOut, EuiButton } from '@elastic/eui'; -import { act } from 'react-dom/test-utils'; -import { httpServiceMock } from '../../../../../../src/core/public/mocks'; - -const docLinks = { ELASTIC_WEBSITE_URL: 'elastic.co/', DOC_LINK_VERSION: 'current' }; - -const http = httpServiceMock.createStartContract(); - -describe('alert action security call out', () => { - let useEffect: any; - - const mockUseEffect = () => { - // make react execute useEffects despite shallow rendering - useEffect.mockImplementationOnce((f: Function) => f()); - }; - - beforeEach(() => { - jest.resetAllMocks(); - useEffect = jest.spyOn(React, 'useEffect'); - mockUseEffect(); - }); - - test('renders nothing while health is loading', async () => { - http.get.mockImplementationOnce(() => new Promise(() => {})); - - let component: ShallowWrapper | undefined; - await act(async () => { - component = shallow( - - ); - }); - - expect(component?.is(Fragment)).toBeTruthy(); - expect(component?.html()).toBe(''); - }); - - test('renders nothing if keys are enabled', async () => { - http.get.mockResolvedValue({ isSufficientlySecure: true }); - - let component: ShallowWrapper | undefined; - await act(async () => { - component = shallow( - - ); - }); - - expect(component?.is(Fragment)).toBeTruthy(); - expect(component?.html()).toBe(''); - }); - - test('renders the callout if keys are disabled', async () => { - http.get.mockResolvedValue({ isSufficientlySecure: false }); - - let component: ShallowWrapper | undefined; - await act(async () => { - component = shallow( - - ); - }); - - expect(component?.find(EuiCallOut).prop('title')).toMatchInlineSnapshot( - `"Alert creation requires TLS between Elasticsearch and Kibana."` - ); - - expect(component?.find(EuiButton).prop('href')).toMatchInlineSnapshot( - `"elastic.co/guide/en/kibana/current/configuring-tls.html"` - ); - }); -}); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/alert_action_security_call_out.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/alert_action_security_call_out.tsx deleted file mode 100644 index f7a80202dff89..0000000000000 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/alert_action_security_call_out.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 React, { Fragment } from 'react'; -import { Option, none, some, fold, filter } from 'fp-ts/lib/Option'; -import { pipe } from 'fp-ts/lib/pipeable'; - -import { EuiCallOut, EuiButton, EuiSpacer } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; -import { FormattedMessage } from '@kbn/i18n/react'; - -import { DocLinksStart, HttpSetup } from 'kibana/public'; -import { AlertingFrameworkHealth } from '../../types'; -import { health } from '../lib/alert_api'; - -interface Props { - docLinks: Pick; - action: string; - http: HttpSetup; -} - -export const AlertActionSecurityCallOut: React.FunctionComponent = ({ - http, - action, - docLinks, -}) => { - const { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION } = docLinks; - - const [alertingHealth, setAlertingHealth] = React.useState>(none); - - React.useEffect(() => { - async function fetchSecurityConfigured() { - setAlertingHealth(some(await health({ http }))); - } - - fetchSecurityConfigured(); - }, [http]); - - return pipe( - alertingHealth, - filter(healthCheck => !healthCheck.isSufficientlySecure), - fold( - () => , - () => ( - - - - - - - - - ) - ) - ); -}; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/health_check.scss b/x-pack/plugins/triggers_actions_ui/public/application/components/health_check.scss new file mode 100644 index 0000000000000..c4d12221e3a01 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/health_check.scss @@ -0,0 +1,13 @@ +@mixin padBannerWith($size) { + padding-left: $size; + padding-right: $size; +} + +.alertingHealthCheck__body { + @include padBannerWith(2 * $euiSize); +} + +.alertingFlyoutHealthCheck__body { + @include padBannerWith(2 * $euiSize); + margin-top: $euiSize; +} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/health_check.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/health_check.test.tsx new file mode 100644 index 0000000000000..5156a6146f3a1 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/health_check.test.tsx @@ -0,0 +1,131 @@ +/* + * 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 { render } from '@testing-library/react'; + +import { HealthCheck } from './health_check'; + +import { act } from 'react-dom/test-utils'; +import { httpServiceMock } from '../../../../../../src/core/public/mocks'; + +const docLinks = { ELASTIC_WEBSITE_URL: 'elastic.co/', DOC_LINK_VERSION: 'current' }; + +const http = httpServiceMock.createStartContract(); + +describe('health check', () => { + test('renders spinner while health is loading', async () => { + http.get.mockImplementationOnce(() => new Promise(() => {})); + + const { queryByText, container } = render( + +

{'shouldnt render'}

+
+ ); + await act(async () => { + // wait for useEffect to run + }); + + expect(container.getElementsByClassName('euiLoadingSpinner').length).toBe(1); + expect(queryByText('shouldnt render')).not.toBeInTheDocument(); + }); + + it('renders children if keys are enabled', async () => { + http.get.mockResolvedValue({ isSufficientlySecure: true, hasPermanentEncryptionKey: true }); + + const { queryByText } = render( + +

{'should render'}

+
+ ); + await act(async () => { + // wait for useEffect to run + }); + expect(queryByText('should render')).toBeInTheDocument(); + }); + + test('renders warning if keys are disabled', async () => { + http.get.mockImplementationOnce(async () => ({ + isSufficientlySecure: false, + hasPermanentEncryptionKey: true, + })); + + const { queryAllByText } = render( + +

{'should render'}

+
+ ); + await act(async () => { + // wait for useEffect to run + }); + + const [description, action] = queryAllByText(/TLS/i); + + expect(description.textContent).toMatchInlineSnapshot( + `"Alerting relies on API keys, which require TLS between Elasticsearch and Kibana. Learn how to enable TLS."` + ); + + expect(action.textContent).toMatchInlineSnapshot(`"Learn how to enable TLS."`); + + expect(action.getAttribute('href')).toMatchInlineSnapshot( + `"elastic.co/guide/en/kibana/current/configuring-tls.html"` + ); + }); + + test('renders warning if encryption key is ephemeral', async () => { + http.get.mockImplementationOnce(async () => ({ + isSufficientlySecure: true, + hasPermanentEncryptionKey: false, + })); + + const { queryByText, queryByRole } = render( + +

{'should render'}

+
+ ); + await act(async () => { + // wait for useEffect to run + }); + + const description = queryByRole(/banner/i); + expect(description!.textContent).toMatchInlineSnapshot( + `"To create an alert, set a value for xpack.encrypted_saved_objects.encryptionKey in your kibana.yml file. Learn how."` + ); + + const action = queryByText(/Learn/i); + expect(action!.textContent).toMatchInlineSnapshot(`"Learn how."`); + expect(action!.getAttribute('href')).toMatchInlineSnapshot( + `"elastic.co/guide/en/kibana/current/alert-action-settings-kb.html#general-alert-action-settings"` + ); + }); + + test('renders warning if encryption key is ephemeral and keys are disabled', async () => { + http.get.mockImplementationOnce(async () => ({ + isSufficientlySecure: false, + hasPermanentEncryptionKey: false, + })); + + const { queryByText } = render( + +

{'should render'}

+
+ ); + await act(async () => { + // wait for useEffect to run + }); + + const description = queryByText(/Transport Layer Security/i); + + expect(description!.textContent).toMatchInlineSnapshot( + `"You must enable Transport Layer Security between Kibana and Elasticsearch and configure an encryption key in your kibana.yml file. Learn how"` + ); + + const action = queryByText(/Learn/i); + expect(action!.textContent).toMatchInlineSnapshot(`"Learn how"`); + expect(action!.getAttribute('href')).toMatchInlineSnapshot( + `"elastic.co/guide/en/kibana/current/alerting-getting-started.html#alerting-setup-prerequisites"` + ); + }); +}); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/health_check.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/health_check.tsx new file mode 100644 index 0000000000000..c967cf5de0771 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/health_check.tsx @@ -0,0 +1,197 @@ +/* + * 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 } from 'react'; +import { Option, none, some, fold } from 'fp-ts/lib/Option'; +import { pipe } from 'fp-ts/lib/pipeable'; +import { FormattedMessage } from '@kbn/i18n/react'; + +import { EuiLink, EuiLoadingSpinner } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; + +import { DocLinksStart, HttpSetup } from 'kibana/public'; + +import { EuiEmptyPrompt, EuiCode } from '@elastic/eui'; +import { AlertingFrameworkHealth } from '../../types'; +import { health } from '../lib/alert_api'; +import './health_check.scss'; + +interface Props { + docLinks: Pick; + http: HttpSetup; + inFlyout?: boolean; +} + +export const HealthCheck: React.FunctionComponent = ({ + docLinks, + http, + children, + inFlyout = false, +}) => { + const [alertingHealth, setAlertingHealth] = React.useState>(none); + + React.useEffect(() => { + (async function() { + setAlertingHealth(some(await health({ http }))); + })(); + }, [http]); + + const className = inFlyout ? 'alertingFlyoutHealthCheck' : 'alertingHealthCheck'; + + return pipe( + alertingHealth, + fold( + () => , + healthCheck => { + return healthCheck?.isSufficientlySecure && healthCheck?.hasPermanentEncryptionKey ? ( + {children} + ) : !healthCheck.isSufficientlySecure && !healthCheck.hasPermanentEncryptionKey ? ( + + ) : !healthCheck.hasPermanentEncryptionKey ? ( + + ) : ( + + ); + } + ) + ); +}; + +type PromptErrorProps = Pick & { + className?: string; +}; + +const TlsAndEncryptionError = ({ + docLinks: { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION }, + className, +}: PromptErrorProps) => ( + + + + } + body={ +
+

+ {i18n.translate('xpack.triggersActionsUI.components.healthCheck.tlsAndEncryptionError', { + defaultMessage: + 'You must enable Transport Layer Security between Kibana and Elasticsearch and configure an encryption key in your kibana.yml file. ', + })} + + {i18n.translate( + 'xpack.triggersActionsUI.components.healthCheck.tlsAndEncryptionErrorAction', + { + defaultMessage: 'Learn how', + } + )} + +

+
+ } + /> +); + +const EncryptionError = ({ + docLinks: { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION }, + className, +}: PromptErrorProps) => ( + + + + } + body={ +
+

+ {i18n.translate( + 'xpack.triggersActionsUI.components.healthCheck.encryptionErrorBeforeKey', + { + defaultMessage: 'To create an alert, set a value for ', + } + )} + {'xpack.encrypted_saved_objects.encryptionKey'} + {i18n.translate( + 'xpack.triggersActionsUI.components.healthCheck.encryptionErrorAfterKey', + { + defaultMessage: ' in your kibana.yml file. ', + } + )} + + {i18n.translate( + 'xpack.triggersActionsUI.components.healthCheck.encryptionErrorAction', + { + defaultMessage: 'Learn how.', + } + )} + +

+
+ } + /> +); + +const TlsError = ({ + docLinks: { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION }, + className, +}: PromptErrorProps) => ( + + + + } + body={ +
+

+ {i18n.translate('xpack.triggersActionsUI.components.healthCheck.tlsError', { + defaultMessage: + 'Alerting relies on API keys, which require TLS between Elasticsearch and Kibana. ', + })} + + {i18n.translate('xpack.triggersActionsUI.components.healthCheck.tlsErrorAction', { + defaultMessage: 'Learn how to enable TLS.', + })} + +

+
+ } + /> +); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/prompts/empty_connectors_prompt.scss b/x-pack/plugins/triggers_actions_ui/public/application/components/prompts/empty_connectors_prompt.scss new file mode 100644 index 0000000000000..fe001ce294ef4 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/prompts/empty_connectors_prompt.scss @@ -0,0 +1,3 @@ +.actEmptyConnectorsPrompt__logo + .actEmptyConnectorsPrompt__logo { + margin-left: $euiSize; +} \ No newline at end of file diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/prompts/empty_connectors_prompt.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/prompts/empty_connectors_prompt.tsx new file mode 100644 index 0000000000000..0e956ea56faa9 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/prompts/empty_connectors_prompt.tsx @@ -0,0 +1,55 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { FormattedMessage } from '@kbn/i18n/react'; +import React, { Fragment } from 'react'; +import { EuiButton, EuiEmptyPrompt, EuiIcon, EuiSpacer, EuiTitle } from '@elastic/eui'; +import './empty_connectors_prompt.scss'; + +export const EmptyConnectorsPrompt = ({ onCTAClicked }: { onCTAClicked: () => void }) => ( + + + + + + +

+ +

+
+
+ } + body={ +

+ +

+ } + actions={ + + + + } + /> +); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/prompts/empty_prompt.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/prompts/empty_prompt.tsx new file mode 100644 index 0000000000000..df593d587de3f --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/prompts/empty_prompt.tsx @@ -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 { FormattedMessage } from '@kbn/i18n/react'; +import React from 'react'; +import { EuiButton, EuiEmptyPrompt } from '@elastic/eui'; + +export const EmptyPrompt = ({ onCTAClicked }: { onCTAClicked: () => void }) => ( + + + + } + body={ +

+ +

+ } + actions={ + + + + } + /> +); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/security_call_out.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/security_call_out.test.tsx deleted file mode 100644 index 28bc02ec3392f..0000000000000 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/security_call_out.test.tsx +++ /dev/null @@ -1,72 +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, { Fragment } from 'react'; -import { shallow, ShallowWrapper } from 'enzyme'; -import { SecurityEnabledCallOut } from './security_call_out'; - -import { EuiCallOut, EuiButton } from '@elastic/eui'; -import { act } from 'react-dom/test-utils'; -import { httpServiceMock } from '../../../../../../src/core/public/mocks'; - -const docLinks = { ELASTIC_WEBSITE_URL: 'elastic.co/', DOC_LINK_VERSION: 'current' }; - -const http = httpServiceMock.createStartContract(); - -describe('security call out', () => { - let useEffect: any; - - const mockUseEffect = () => { - // make react execute useEffects despite shallow rendering - useEffect.mockImplementationOnce((f: Function) => f()); - }; - - beforeEach(() => { - jest.resetAllMocks(); - useEffect = jest.spyOn(React, 'useEffect'); - mockUseEffect(); - }); - - test('renders nothing while health is loading', async () => { - http.get.mockImplementationOnce(() => new Promise(() => {})); - - let component: ShallowWrapper | undefined; - await act(async () => { - component = shallow(); - }); - - expect(component?.is(Fragment)).toBeTruthy(); - expect(component?.html()).toBe(''); - }); - - test('renders nothing if keys are enabled', async () => { - http.get.mockResolvedValue({ isSufficientlySecure: true }); - - let component: ShallowWrapper | undefined; - await act(async () => { - component = shallow(); - }); - - expect(component?.is(Fragment)).toBeTruthy(); - expect(component?.html()).toBe(''); - }); - - test('renders the callout if keys are disabled', async () => { - http.get.mockImplementationOnce(async () => ({ isSufficientlySecure: false })); - - let component: ShallowWrapper | undefined; - await act(async () => { - component = shallow(); - }); - - expect(component?.find(EuiCallOut).prop('title')).toMatchInlineSnapshot( - `"Enable Transport Layer Security"` - ); - - expect(component?.find(EuiButton).prop('href')).toMatchInlineSnapshot( - `"elastic.co/guide/en/kibana/current/configuring-tls.html"` - ); - }); -}); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/security_call_out.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/security_call_out.tsx deleted file mode 100644 index 9874a3a0697d2..0000000000000 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/security_call_out.tsx +++ /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 React, { Fragment } from 'react'; -import { Option, none, some, fold, filter } from 'fp-ts/lib/Option'; -import { pipe } from 'fp-ts/lib/pipeable'; - -import { EuiCallOut, EuiButton, EuiSpacer } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; -import { FormattedMessage } from '@kbn/i18n/react'; - -import { DocLinksStart, HttpSetup } from 'kibana/public'; - -import { AlertingFrameworkHealth } from '../../types'; -import { health } from '../lib/alert_api'; - -interface Props { - docLinks: Pick; - http: HttpSetup; -} - -export const SecurityEnabledCallOut: React.FunctionComponent = ({ docLinks, http }) => { - const { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION } = docLinks; - - const [alertingHealth, setAlertingHealth] = React.useState>(none); - - React.useEffect(() => { - async function fetchSecurityConfigured() { - setAlertingHealth(some(await health({ http }))); - } - - fetchSecurityConfigured(); - }, [http]); - - return pipe( - alertingHealth, - filter(healthCheck => !healthCheck?.isSufficientlySecure), - fold( - () => , - () => ( - - -

- -

- - - -
- -
- ) - ) - ); -}; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/home.tsx b/x-pack/plugins/triggers_actions_ui/public/application/home.tsx index 7c8d798984bf2..4d0a9980f2231 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/home.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/home.tsx @@ -29,8 +29,8 @@ import { hasShowActionsCapability, hasShowAlertsCapability } from './lib/capabil import { ActionsConnectorsList } from './sections/actions_connectors_list/components/actions_connectors_list'; import { AlertsList } from './sections/alerts_list/components/alerts_list'; -import { SecurityEnabledCallOut } from './components/security_call_out'; import { PLUGIN } from './constants/plugin'; +import { HealthCheck } from './components/health_check'; interface MatchParams { section: Section; @@ -88,7 +88,6 @@ export const TriggersActionsUIHome: React.FunctionComponent - @@ -142,9 +141,27 @@ export const TriggersActionsUIHome: React.FunctionComponent {canShowActions && ( - + ( + + + + )} + /> + )} + {canShowAlerts && ( + ( + + + + )} + /> )} - {canShowAlerts && } diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.scss b/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.scss index 3d65b8a799b1b..70ad1cae6c1d1 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.scss +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.scss @@ -1,7 +1,3 @@ -.actConnectorsList__logo + .actConnectorsList__logo { - margin-left: $euiSize; -} - .actConnectorsList__tableRowDisabled { background-color: $euiColorLightestShade; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.tsx index 81693e1d2d9d1..47e058f473946 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.tsx @@ -10,9 +10,6 @@ import { EuiInMemoryTable, EuiSpacer, EuiButton, - EuiIcon, - EuiEmptyPrompt, - EuiTitle, EuiLink, EuiLoadingSpinner, EuiIconTip, @@ -30,6 +27,7 @@ import { ActionsConnectorsContextProvider } from '../../../context/actions_conne import { checkActionTypeEnabled } from '../../../lib/check_action_type_enabled'; import './actions_connectors_list.scss'; import { ActionConnector, ActionConnectorTableItem, ActionTypeIndex } from '../../../../types'; +import { EmptyConnectorsPrompt } from '../../../components/prompts/empty_connectors_prompt'; export const ActionsConnectorsList: React.FunctionComponent = () => { const { http, toastNotifications, capabilities, actionTypeRegistry } = useAppDependencies(); @@ -324,51 +322,6 @@ export const ActionsConnectorsList: React.FunctionComponent = () => { /> ); - const emptyPrompt = ( - - - - - - -

- -

-
-
- } - body={ -

- -

- } - actions={ - setAddFlyoutVisibility(true)} - > - - - } - /> - ); - const noPermissionPrompt = (

{ )} {data.length !== 0 && table} - {data.length === 0 && canSave && !isLoadingActions && !isLoadingActionTypes && emptyPrompt} + {data.length === 0 && canSave && !isLoadingActions && !isLoadingActionTypes && ( + setAddFlyoutVisibility(true)} /> + )} {data.length === 0 && !canSave && noPermissionPrompt} { docLinks: { ELASTIC_WEBSITE_URL: '', DOC_LINK_VERSION: '' }, }; - mockes.http.get.mockResolvedValue({ isSufficientlySecure: true }); + mockes.http.get.mockResolvedValue({ + isSufficientlySecure: true, + hasPermanentEncryptionKey: true, + }); const alertType = { id: 'my-alert-type', diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_add.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_add.tsx index e025248fad52e..0620ced6365a9 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_add.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_add.tsx @@ -25,7 +25,7 @@ import { Alert, AlertAction, IErrorObject } from '../../../types'; import { AlertForm, validateBaseProperties } from './alert_form'; import { alertReducer } from './alert_reducer'; import { createAlert } from '../../lib/alert_api'; -import { AlertActionSecurityCallOut } from '../../components/alert_action_security_call_out'; +import { HealthCheck } from '../../components/health_check'; import { PLUGIN } from '../../constants/plugin'; interface AlertAddProps { @@ -154,62 +154,54 @@ export const AlertAdd = ({

- - - - - - - - - {i18n.translate('xpack.triggersActionsUI.sections.alertAdd.cancelButtonLabel', { - defaultMessage: 'Cancel', - })} - - - - { - setIsSaving(true); - const savedAlert = await onSaveAlert(); - setIsSaving(false); - if (savedAlert) { - closeFlyout(); - if (reloadAlerts) { - reloadAlerts(); + + + + + + + + + {i18n.translate('xpack.triggersActionsUI.sections.alertAdd.cancelButtonLabel', { + defaultMessage: 'Cancel', + })} + + + + { + setIsSaving(true); + const savedAlert = await onSaveAlert(); + setIsSaving(false); + if (savedAlert) { + closeFlyout(); + if (reloadAlerts) { + reloadAlerts(); + } } - } - }} - > - - - - - + }} + > + + + + + + ); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_edit.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_edit.test.tsx index 6fcfb463c4c77..916ba368e0732 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_edit.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_edit.test.tsx @@ -36,7 +36,10 @@ describe('alert_edit', () => { docLinks: { ELASTIC_WEBSITE_URL: '', DOC_LINK_VERSION: '' }, }; - mockedCoreSetup.http.get.mockResolvedValue({ isSufficientlySecure: true }); + mockedCoreSetup.http.get.mockResolvedValue({ + isSufficientlySecure: true, + hasPermanentEncryptionKey: true, + }); const alertType = { id: 'my-alert-type', diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_edit.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_edit.tsx index 3f27a7860bafa..4255eca83be47 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_edit.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_edit.tsx @@ -26,7 +26,7 @@ import { Alert, AlertAction, IErrorObject } from '../../../types'; import { AlertForm, validateBaseProperties } from './alert_form'; import { alertReducer } from './alert_reducer'; import { updateAlert } from '../../lib/alert_api'; -import { AlertActionSecurityCallOut } from '../../components/alert_action_security_call_out'; +import { HealthCheck } from '../../components/health_check'; import { PLUGIN } from '../../constants/plugin'; interface AlertEditProps { @@ -137,77 +137,69 @@ export const AlertEdit = ({ - - - {hasActionsDisabled && ( - - - - - )} - - - - - - - {i18n.translate('xpack.triggersActionsUI.sections.alertEdit.cancelButtonLabel', { - defaultMessage: 'Cancel', - })} - - - - { - setIsSaving(true); - const savedAlert = await onSaveAlert(); - setIsSaving(false); - if (savedAlert) { - closeFlyout(); - if (reloadAlerts) { - reloadAlerts(); - } - } - }} - > - + + {hasActionsDisabled && ( + + - - - - + + + )} + + + + + + + {i18n.translate('xpack.triggersActionsUI.sections.alertEdit.cancelButtonLabel', { + defaultMessage: 'Cancel', + })} + + + + { + setIsSaving(true); + const savedAlert = await onSaveAlert(); + setIsSaving(false); + if (savedAlert) { + closeFlyout(); + if (reloadAlerts) { + reloadAlerts(); + } + } + }} + > + + + + + + ); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.tsx index afd3299f0c2bb..5d59180ff572b 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.tsx @@ -15,7 +15,6 @@ import { EuiFlexItem, EuiIcon, EuiSpacer, - EuiEmptyPrompt, EuiLink, EuiLoadingSpinner, } from '@elastic/eui'; @@ -36,6 +35,7 @@ import { loadActionTypes } from '../../../lib/action_connector_api'; import { hasDeleteAlertsCapability, hasSaveAlertsCapability } from '../../../lib/capabilities'; import { routeToAlertDetails, DEFAULT_SEARCH_PAGE_SIZE } from '../../../constants'; import { DeleteModalConfirmation } from '../../../components/delete_modal_confirmation'; +import { EmptyPrompt } from '../../../components/prompts/empty_prompt'; const ENTER_KEY = 13; @@ -292,44 +292,6 @@ export const AlertsList: React.FunctionComponent = () => { ); } - const emptyPrompt = ( - - - - } - body={ -

- -

- } - actions={ - setAlertFlyoutVisibility(true)} - > - - - } - /> - ); - const table = ( @@ -473,7 +435,7 @@ export const AlertsList: React.FunctionComponent = () => { ) : ( - emptyPrompt + setAlertFlyoutVisibility(true)} /> )} Date: Thu, 9 Apr 2020 00:56:52 +0300 Subject: [PATCH 35/40] [APM] Agent remote configuration: changes in Java property descriptions (#62282) * [APM] Agent remote configuration: changes in Java property descriptions * Removing newlines * Update snapshot Co-authored-by: Elastic Machine Co-authored-by: Brandon Morelli Co-authored-by: Nathan L Smith --- .../__snapshots__/index.test.ts.snap | 5 +++-- .../setting_definitions/java_settings.ts | 12 ++++++------ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/x-pack/plugins/apm/common/agent_configuration/setting_definitions/__snapshots__/index.test.ts.snap b/x-pack/plugins/apm/common/agent_configuration/setting_definitions/__snapshots__/index.test.ts.snap index bc435179762a2..49840d2157af7 100644 --- a/x-pack/plugins/apm/common/agent_configuration/setting_definitions/__snapshots__/index.test.ts.snap +++ b/x-pack/plugins/apm/common/agent_configuration/setting_definitions/__snapshots__/index.test.ts.snap @@ -153,8 +153,9 @@ Array [ }, Object { "key": "stress_monitor_gc_stress_threshold", - "type": "boolean", - "validationName": "(\\"true\\" | \\"false\\")", + "type": "float", + "validationError": "Must be a number between 0.000 and 1", + "validationName": "numberFloatRt", }, Object { "key": "stress_monitor_system_cpu_relief_threshold", diff --git a/x-pack/plugins/apm/common/agent_configuration/setting_definitions/java_settings.ts b/x-pack/plugins/apm/common/agent_configuration/setting_definitions/java_settings.ts index bb050076b9f9a..2e10c74378549 100644 --- a/x-pack/plugins/apm/common/agent_configuration/setting_definitions/java_settings.ts +++ b/x-pack/plugins/apm/common/agent_configuration/setting_definitions/java_settings.ts @@ -20,7 +20,7 @@ export const javaSettings: RawSettingDefinition[] = [ 'xpack.apm.agentConfig.enableLogCorrelation.description', { defaultMessage: - "A boolean specifying if the agent should integrate into SLF4J's MDC to enable trace-log correlation. If set to `true`, the agent will set the `trace.id` and `transaction.id` for the currently active spans and transactions to the MDC. While it's allowed to enable this setting at runtime, you can't disable it without a restart." + "A boolean specifying if the agent should integrate into SLF4J's MDC to enable trace-log correlation. If set to `true`, the agent will set the `trace.id` and `transaction.id` for the currently active spans and transactions to the MDC. Since Java agent version 1.16.0, the agent also adds `error.id` of captured error to the MDC just before the error message is logged. NOTE: While it's allowed to enable this setting at runtime, you can't disable it without a restart." } ), includeAgents: ['java'] @@ -41,7 +41,7 @@ export const javaSettings: RawSettingDefinition[] = [ 'xpack.apm.agentConfig.circuitBreakerEnabled.description', { defaultMessage: - 'A boolean specifying whether the circuit breaker should be enabled or not. When enabled, the agent periodically polls stress monitors to detect system/process/JVM stress state. If ANY of the monitors detects a stress indication, the agent will become inactive, as if the `active` configuration option has been set to `false`, thus reducing resource consumption to a minimum. When inactive, the agent continues polling the same monitors in order to detect whether the stress state has been relieved. If ALL monitors approve that the system/process/JVM is not under stress anymore, the agent will resume and become fully functional.' + 'A boolean specifying whether the circuit breaker should be enabled or not. When enabled, the agent periodically polls stress monitors to detect system/process/JVM stress state. If ANY of the monitors detects a stress indication, the agent will pause, as if the `recording` configuration option has been set to `false`, thus reducing resource consumption to a minimum. When paused, the agent continues polling the same monitors in order to detect whether the stress state has been relieved. If ALL monitors approve that the system/process/JVM is not under stress anymore, the agent will resume and become fully functional.' } ), includeAgents: ['java'] @@ -52,7 +52,7 @@ export const javaSettings: RawSettingDefinition[] = [ 'xpack.apm.agentConfig.stressMonitorGcStressThreshold.label', { defaultMessage: 'Stress monitor gc stress threshold' } ), - type: 'boolean', + type: 'float', category: 'Circuit-Breaker', defaultValue: '0.95', description: i18n.translate( @@ -155,7 +155,7 @@ export const javaSettings: RawSettingDefinition[] = [ 'xpack.apm.agentConfig.profilingInferredSpansEnabled.description', { defaultMessage: - 'Set to `true` to make the agent create spans for method executions based on async-profiler, a sampling aka statistical profiler. Due to the nature of how sampling profilers work, the duration of the inferred spans are not exact, but only estimations. The `profiling_inferred_spans_sampling_interval` lets you fine tune the trade-off between accuracy and overhead. The inferred spans are created after a profiling session has ended. This means there is a delay between the regular and the inferred spans being visible in the UI. This feature is not available on Windows' + 'Set to `true` to make the agent create spans for method executions based on async-profiler, a sampling aka statistical profiler. Due to the nature of how sampling profilers work, the duration of the inferred spans are not exact, but only estimations. The `profiling_inferred_spans_sampling_interval` lets you fine tune the trade-off between accuracy and overhead. The inferred spans are created after a profiling session has ended. This means there is a delay between the regular and the inferred spans being visible in the UI. NOTE: This feature is not available on Windows.' } ), includeAgents: ['java'] @@ -209,7 +209,7 @@ export const javaSettings: RawSettingDefinition[] = [ 'xpack.apm.agentConfig.profilingInferredSpansIncludedClasses.description', { defaultMessage: - 'If set, the agent will only create inferred spans for methods which match this list. Setting a value may slightly increase performance and can reduce clutter by only creating spans for the classes you are interested in. Example: `org.example.myapp.*` This option supports the wildcard `*`, which matches zero or more characters. Examples: `/foo/*/bar/*/baz*`, `*foo*`. Matching is case insensitive by default. Prepending an element with `(?-i)` makes the matching case sensitive.' + 'If set, the agent will only create inferred spans for methods which match this list. Setting a value may slightly reduce overhead and can reduce clutter by only creating spans for the classes you are interested in. This option supports the wildcard `*`, which matches zero or more characters. Example: `org.example.myapp.*`. Matching is case insensitive by default. Prepending an element with `(?-i)` makes the matching case sensitive.' } ), includeAgents: ['java'] @@ -228,7 +228,7 @@ export const javaSettings: RawSettingDefinition[] = [ 'xpack.apm.agentConfig.profilingInferredSpansExcludedClasses.description', { defaultMessage: - 'Excludes classes for which no profiler-inferred spans should be created. This option supports the wildcard `*`, which matches zero or more characters. Examples: `/foo/*/bar/*/baz*`, `*foo*`. Matching is case insensitive by default. Prepending an element with `(?-i)` makes the matching case sensitive.' + 'Excludes classes for which no profiler-inferred spans should be created. This option supports the wildcard `*`, which matches zero or more characters. Matching is case insensitive by default. Prepending an element with `(?-i)` makes the matching case sensitive.' } ), includeAgents: ['java'] From 0c35762f2702c813dfb74c37bae4364eecfc95c4 Mon Sep 17 00:00:00 2001 From: Brittany Joiner Date: Wed, 8 Apr 2020 18:08:13 -0500 Subject: [PATCH 36/40] Add Error Exception Type Column (#59596) * start of error exception type * width and link * removed extra line * updated snapshot * updated snapshots * updated snapshots * Update snapshots Co-authored-by: Elastic Machine Co-authored-by: Nathan L Smith --- .../__test__/__snapshots__/List.test.tsx.snap | 287 ++++++++++++++++-- .../app/ErrorGroupOverview/List/index.tsx | 36 ++- .../elasticsearch_fieldnames.test.ts.snap | 6 + .../apm/common/elasticsearch_fieldnames.ts | 1 + .../errors/__snapshots__/queries.test.ts.snap | 2 + .../apm/server/lib/errors/get_error_groups.ts | 6 +- 6 files changed, 306 insertions(+), 32 deletions(-) diff --git a/x-pack/legacy/plugins/apm/public/components/app/ErrorGroupOverview/List/__test__/__snapshots__/List.test.tsx.snap b/x-pack/legacy/plugins/apm/public/components/app/ErrorGroupOverview/List/__test__/__snapshots__/List.test.tsx.snap index 205a303bcf47b..afa0cb51cd108 100644 --- a/x-pack/legacy/plugins/apm/public/components/app/ErrorGroupOverview/List/__test__/__snapshots__/List.test.tsx.snap +++ b/x-pack/legacy/plugins/apm/public/components/app/ErrorGroupOverview/List/__test__/__snapshots__/List.test.tsx.snap @@ -11,6 +11,12 @@ exports[`ErrorGroupOverview -> List should render empty state 1`] = ` "sortable": false, "width": "96px", }, + Object { + "field": "type", + "name": "Type", + "render": [Function], + "sortable": false, + }, Object { "field": "message", "name": "Error message and culprit", @@ -142,7 +148,28 @@ exports[`ErrorGroupOverview -> List should render empty state 1`] = ` +
+ + Type + +
+ + List should render empty state 1`] = ` List should render empty state 1`] = ` aria-live="polite" aria-sort="descending" className="euiTableHeaderCell" - data-test-subj="tableHeaderCell_occurrenceCount_3" + data-test-subj="tableHeaderCell_occurrenceCount_4" role="columnheader" scope="col" style={ @@ -225,7 +252,7 @@ exports[`ErrorGroupOverview -> List should render empty state 1`] = ` aria-live="polite" aria-sort="none" className="euiTableHeaderCell" - data-test-subj="tableHeaderCell_latestOccurrenceAt_4" + data-test-subj="tableHeaderCell_latestOccurrenceAt_5" role="columnheader" scope="col" style={ @@ -264,7 +291,7 @@ exports[`ErrorGroupOverview -> List should render empty state 1`] = ` > List should render with data 1`] = ` font-family: "Roboto Mono",Consolas,Menlo,Courier,monospace; } +.c2 { + max-width: 100%; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + .c1 { max-width: 100%; white-space: nowrap; @@ -301,7 +335,7 @@ exports[`ErrorGroupOverview -> List should render with data 1`] = ` text-overflow: ellipsis; } -.c2 { +.c3 { font-family: "Roboto Mono",Consolas,Menlo,Courier,monospace; font-size: 16px; max-width: 100%; @@ -310,7 +344,7 @@ exports[`ErrorGroupOverview -> List should render with data 1`] = ` text-overflow: ellipsis; } -.c3 { +.c4 { font-family: "Roboto Mono",Consolas,Menlo,Courier,monospace; } @@ -324,6 +358,12 @@ exports[`ErrorGroupOverview -> List should render with data 1`] = ` "sortable": false, "width": "96px", }, + Object { + "field": "type", + "name": "Type", + "render": [Function], + "sortable": false, + }, Object { "field": "message", "name": "Error message and culprit", @@ -486,7 +526,28 @@ exports[`ErrorGroupOverview -> List should render with data 1`] = ` +
+ + Type + +
+ + List should render with data 1`] = ` List should render with data 1`] = ` aria-live="polite" aria-sort="descending" className="euiTableHeaderCell" - data-test-subj="tableHeaderCell_occurrenceCount_3" + data-test-subj="tableHeaderCell_occurrenceCount_4" role="columnheader" scope="col" style={ @@ -569,7 +630,7 @@ exports[`ErrorGroupOverview -> List should render with data 1`] = ` aria-live="polite" aria-sort="none" className="euiTableHeaderCell" - data-test-subj="tableHeaderCell_latestOccurrenceAt_4" + data-test-subj="tableHeaderCell_latestOccurrenceAt_5" role="columnheader" scope="col" style={ @@ -642,6 +703,49 @@ exports[`ErrorGroupOverview -> List should render with data 1`] = `
+ +
+ Type +
+ + List should render with data 1`] = ` className="" >
List should render with data 1`] = ` serviceName="opbeans-python" > List should render with data 1`] = ` onFocus={[Function]} >
@@ -812,6 +916,49 @@ exports[`ErrorGroupOverview -> List should render with data 1`] = `
+ +
+ Type +
+
+ List should render with data 1`] = ` className="" >
List should render with data 1`] = ` serviceName="opbeans-python" > List should render with data 1`] = ` onFocus={[Function]} >
@@ -982,6 +1129,49 @@ exports[`ErrorGroupOverview -> List should render with data 1`] = `
+ +
+ Type +
+
+ List should render with data 1`] = ` className="" >
List should render with data 1`] = ` serviceName="opbeans-python" > List should render with data 1`] = ` onFocus={[Function]} >
@@ -1152,6 +1342,49 @@ exports[`ErrorGroupOverview -> List should render with data 1`] = `
+ +
+ Type +
+
+ List should render with data 1`] = ` className="" >
List should render with data 1`] = ` serviceName="opbeans-python" > List should render with data 1`] = ` onFocus={[Function]} >
diff --git a/x-pack/legacy/plugins/apm/public/components/app/ErrorGroupOverview/List/index.tsx b/x-pack/legacy/plugins/apm/public/components/app/ErrorGroupOverview/List/index.tsx index b26833c02fe22..250b9a5d188d0 100644 --- a/x-pack/legacy/plugins/apm/public/components/app/ErrorGroupOverview/List/index.tsx +++ b/x-pack/legacy/plugins/apm/public/components/app/ErrorGroupOverview/List/index.tsx @@ -23,6 +23,8 @@ import { useUrlParams } from '../../../../hooks/useUrlParams'; import { ManagedTable } from '../../../shared/ManagedTable'; import { ErrorDetailLink } from '../../../shared/Links/apm/ErrorDetailLink'; import { TimestampTooltip } from '../../../shared/TimestampTooltip'; +import { ErrorOverviewLink } from '../../../shared/Links/apm/ErrorOverviewLink'; +import { APMQueryParams } from '../../../shared/Links/url_helpers'; const GroupIdLink = styled(ErrorDetailLink)` font-family: ${fontFamilyCode}; @@ -32,6 +34,10 @@ const MessageAndCulpritCell = styled.div` ${truncate('100%')}; `; +const ErrorLink = styled(ErrorOverviewLink)` + ${truncate('100%')}; +`; + const MessageLink = styled(ErrorDetailLink)` font-family: ${fontFamilyCode}; font-size: ${fontSizes.large}; @@ -48,9 +54,8 @@ interface Props { const ErrorGroupList: React.FC = props => { const { items } = props; - const { - urlParams: { serviceName } - } = useUrlParams(); + const { urlParams } = useUrlParams(); + const { serviceName } = urlParams; if (!serviceName) { throw new Error('Service name is required'); @@ -73,6 +78,29 @@ const ErrorGroupList: React.FC = props => { ); } }, + { + name: i18n.translate('xpack.apm.errorsTable.typeColumnLabel', { + defaultMessage: 'Type' + }), + field: 'type', + sortable: false, + render: (type: string, item: ErrorGroupListAPIResponse[0]) => { + return ( + + {type} + + ); + } + }, { name: i18n.translate( 'xpack.apm.errorsTable.errorMessageAndCulpritColumnLabel', @@ -150,7 +178,7 @@ const ErrorGroupList: React.FC = props => { ) } ], - [serviceName] + [serviceName, urlParams] ); return ( diff --git a/x-pack/plugins/apm/common/__snapshots__/elasticsearch_fieldnames.test.ts.snap b/x-pack/plugins/apm/common/__snapshots__/elasticsearch_fieldnames.test.ts.snap index 5de82a9ee8788..54dd4704edfc0 100644 --- a/x-pack/plugins/apm/common/__snapshots__/elasticsearch_fieldnames.test.ts.snap +++ b/x-pack/plugins/apm/common/__snapshots__/elasticsearch_fieldnames.test.ts.snap @@ -16,6 +16,8 @@ exports[`Error ERROR_EXC_HANDLED 1`] = `undefined`; exports[`Error ERROR_EXC_MESSAGE 1`] = `undefined`; +exports[`Error ERROR_EXC_TYPE 1`] = `undefined`; + exports[`Error ERROR_GROUP_ID 1`] = `"grouping key"`; exports[`Error ERROR_LOG_LEVEL 1`] = `undefined`; @@ -144,6 +146,8 @@ exports[`Span ERROR_EXC_HANDLED 1`] = `undefined`; exports[`Span ERROR_EXC_MESSAGE 1`] = `undefined`; +exports[`Span ERROR_EXC_TYPE 1`] = `undefined`; + exports[`Span ERROR_GROUP_ID 1`] = `undefined`; exports[`Span ERROR_LOG_LEVEL 1`] = `undefined`; @@ -272,6 +276,8 @@ exports[`Transaction ERROR_EXC_HANDLED 1`] = `undefined`; exports[`Transaction ERROR_EXC_MESSAGE 1`] = `undefined`; +exports[`Transaction ERROR_EXC_TYPE 1`] = `undefined`; + exports[`Transaction ERROR_GROUP_ID 1`] = `undefined`; exports[`Transaction ERROR_LOG_LEVEL 1`] = `undefined`; diff --git a/x-pack/plugins/apm/common/elasticsearch_fieldnames.ts b/x-pack/plugins/apm/common/elasticsearch_fieldnames.ts index bc1b346f50da7..d5c3f91eb9247 100644 --- a/x-pack/plugins/apm/common/elasticsearch_fieldnames.ts +++ b/x-pack/plugins/apm/common/elasticsearch_fieldnames.ts @@ -60,6 +60,7 @@ export const ERROR_LOG_LEVEL = 'error.log.level'; export const ERROR_LOG_MESSAGE = 'error.log.message'; export const ERROR_EXC_MESSAGE = 'error.exception.message'; // only to be used in es queries, since error.exception is now an array export const ERROR_EXC_HANDLED = 'error.exception.handled'; // only to be used in es queries, since error.exception is now an array +export const ERROR_EXC_TYPE = 'error.exception.type'; export const ERROR_PAGE_URL = 'error.page.url'; // METRICS diff --git a/x-pack/plugins/apm/server/lib/errors/__snapshots__/queries.test.ts.snap b/x-pack/plugins/apm/server/lib/errors/__snapshots__/queries.test.ts.snap index b9ac9d5431700..982ad558dc91d 100644 --- a/x-pack/plugins/apm/server/lib/errors/__snapshots__/queries.test.ts.snap +++ b/x-pack/plugins/apm/server/lib/errors/__snapshots__/queries.test.ts.snap @@ -73,6 +73,7 @@ Object { "error.log.message", "error.exception.message", "error.exception.handled", + "error.exception.type", "error.culprit", "error.grouping_key", "@timestamp", @@ -148,6 +149,7 @@ Object { "error.log.message", "error.exception.message", "error.exception.handled", + "error.exception.type", "error.culprit", "error.grouping_key", "@timestamp", diff --git a/x-pack/plugins/apm/server/lib/errors/get_error_groups.ts b/x-pack/plugins/apm/server/lib/errors/get_error_groups.ts index 8ea6df5a9898a..5221d737866f4 100644 --- a/x-pack/plugins/apm/server/lib/errors/get_error_groups.ts +++ b/x-pack/plugins/apm/server/lib/errors/get_error_groups.ts @@ -8,6 +8,7 @@ import { ERROR_CULPRIT, ERROR_EXC_HANDLED, ERROR_EXC_MESSAGE, + ERROR_EXC_TYPE, ERROR_GROUP_ID, ERROR_LOG_MESSAGE } from '../../../common/elasticsearch_fieldnames'; @@ -67,6 +68,7 @@ export async function getErrorGroups({ ERROR_LOG_MESSAGE, ERROR_EXC_MESSAGE, ERROR_EXC_HANDLED, + ERROR_EXC_TYPE, ERROR_CULPRIT, ERROR_GROUP_ID, '@timestamp' @@ -99,6 +101,7 @@ export async function getErrorGroups({ exception?: Array<{ handled?: boolean; message?: string; + type?: string; }>; culprit: APMError['error']['culprit']; grouping_key: APMError['error']['grouping_key']; @@ -120,7 +123,8 @@ export async function getErrorGroups({ culprit: source.error.culprit, groupId: source.error.grouping_key, latestOccurrenceAt: source['@timestamp'], - handled: source.error.exception?.[0].handled + handled: source.error.exception?.[0].handled, + type: source.error.exception?.[0].type }; }); From c643148f3613df41565a25e49b0f8c88fb17876a Mon Sep 17 00:00:00 2001 From: Frank Hassanabad Date: Wed, 8 Apr 2020 17:36:20 -0600 Subject: [PATCH 37/40] [SIEM][Detection Engine] Fix rule notification critical bugs ## Summary Fixes critical bugs found during testing of the rule notification. * Fixes a bug where when you turn on rules quickly such as ML rules you would see these message below. This message can also be seen when you first create a rule with an action notification. This is a race condition with how we update rules multiple times when we really should only update it once and do it before enabling a rule ``` server log [12:18:35.986] [error][alerting][alerting][plugins][plugins] Executing Alert "63b828b5-24b9-4d55-83ee-8a8201fe2d76" has resulted in Error: [security_exception] missing authentication credentials for REST request [/_security/user/_has_privileges], with { header={ WWW-Authenticate={ 0="Bearer realm=\"security\"" & 1="ApiKey" & 2="Basic realm=\"security\" charset=\"UTF-8\"" } } ``` * Fixes a bug where we were using `ruleParams.interval` when we should have been using `ruleAlertSavedObject.attributes.schedule.interval`. When changing rule notifications to run daily, weekly, etc.. you would see this exception being thrown: ``` server log [21:23:08.028] [error][alerting][alerting][plugins][plugins] Executing Alert "fedcccc0-7c69-4e2f-83f8-d8ee88ab5484" has resulted in Error: "from" or "to" was not provided to signals count query ``` * Fixes misc typing issues found * Fixes it to where we no longer make multiple DB calls but rather pass down objects we already have. * Changes the work flow to where we only update, create, or patch the alerting object once which fixes the race condition and improves the backend performance. * Removes left over unused code * Applied https://en.wikipedia.org/wiki/Single-entry_single-exit to functions where it made sense and easier to read. ### Checklist - [x] [Unit or functional tests](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#cross-browser-compatibility) were updated or added to match the most common scenarios --- .../legacy/plugins/siem/common/constants.ts | 2 - .../notifications/add_tags.ts | 2 +- .../create_notifications.test.ts | 2 - .../notifications/create_notifications.ts | 5 +- .../rules_notification_alert_type.ts | 4 +- .../detection_engine/notifications/types.ts | 9 ++-- .../update_notifications.test.ts | 9 +--- .../notifications/update_notifications.ts | 27 ++++------ .../routes/rules/create_rules_bulk_route.ts | 1 + .../routes/rules/create_rules_route.ts | 1 + .../routes/rules/import_rules_route.ts | 1 + .../routes/rules/update_rules_bulk_route.ts | 1 + .../routes/rules/update_rules_route.ts | 1 + .../create_rule_actions_saved_object.ts | 8 +-- .../delete_rule_actions_saved_object.ts | 9 ++-- .../get_rule_actions_saved_object.ts | 16 +++--- ...ate_or_create_rule_actions_saved_object.ts | 11 ++-- .../update_rule_actions_saved_object.ts | 15 ++---- .../rules/create_rules.test.ts | 1 + .../detection_engine/rules/create_rules.ts | 4 +- .../rules/install_prepacked_rules.ts | 1 + .../lib/detection_engine/rules/patch_rules.ts | 2 +- .../lib/detection_engine/rules/types.ts | 6 +-- .../rules/update_rule_actions.ts | 54 ------------------- .../rules/update_rules.test.ts | 3 ++ .../detection_engine/rules/update_rules.ts | 6 ++- .../rules/update_rules_notifications.ts | 9 +--- .../lib/detection_engine/signals/types.ts | 7 ++- 28 files changed, 75 insertions(+), 142 deletions(-) delete mode 100644 x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/update_rule_actions.ts diff --git a/x-pack/legacy/plugins/siem/common/constants.ts b/x-pack/legacy/plugins/siem/common/constants.ts index 662fb8fb8ef68..22f1b3beffa35 100644 --- a/x-pack/legacy/plugins/siem/common/constants.ts +++ b/x-pack/legacy/plugins/siem/common/constants.ts @@ -65,8 +65,6 @@ export const INTERNAL_IDENTIFIER = '__internal'; export const INTERNAL_RULE_ID_KEY = `${INTERNAL_IDENTIFIER}_rule_id`; export const INTERNAL_RULE_ALERT_ID_KEY = `${INTERNAL_IDENTIFIER}_rule_alert_id`; export const INTERNAL_IMMUTABLE_KEY = `${INTERNAL_IDENTIFIER}_immutable`; -export const INTERNAL_NOTIFICATION_ID_KEY = `${INTERNAL_IDENTIFIER}_notification_id`; -export const INTERNAL_NOTIFICATION_RULE_ID_KEY = `${INTERNAL_IDENTIFIER}_notification_rule_id`; /** * Detection engine routes diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/notifications/add_tags.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/notifications/add_tags.ts index 6955e57d099be..14b2e1ae9e366 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/notifications/add_tags.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/notifications/add_tags.ts @@ -6,5 +6,5 @@ import { INTERNAL_RULE_ALERT_ID_KEY } from '../../../../common/constants'; -export const addTags = (tags: string[] = [], ruleAlertId: string): string[] => +export const addTags = (tags: string[], ruleAlertId: string): string[] => Array.from(new Set([...tags, `${INTERNAL_RULE_ALERT_ID_KEY}:${ruleAlertId}`])); diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/notifications/create_notifications.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/notifications/create_notifications.test.ts index 073251b68f414..3878f5dae8889 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/notifications/create_notifications.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/notifications/create_notifications.test.ts @@ -24,7 +24,6 @@ describe('createNotifications', () => { enabled: true, interval: '', name: '', - tags: [], }); expect(alertsClient.create).toHaveBeenCalledWith( @@ -52,7 +51,6 @@ describe('createNotifications', () => { enabled: true, interval: '', name: '', - tags: [], }); expect(alertsClient.create).toHaveBeenCalledWith( diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/notifications/create_notifications.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/notifications/create_notifications.ts index 3a1697f1c8afc..ccd7576255d83 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/notifications/create_notifications.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/notifications/create_notifications.ts @@ -17,12 +17,11 @@ export const createNotifications = async ({ ruleAlertId, interval, name, - tags, }: CreateNotificationParams): Promise => alertsClient.create({ data: { name, - tags: addTags(tags, ruleAlertId), + tags: addTags([], ruleAlertId), alertTypeId: NOTIFICATIONS_ID, consumer: APP_ID, params: { @@ -30,7 +29,7 @@ export const createNotifications = async ({ }, schedule: { interval }, enabled, - actions: actions?.map(transformRuleToAlertAction), + actions: actions.map(transformRuleToAlertAction), throttle: null, }, }); diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/notifications/rules_notification_alert_type.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/notifications/rules_notification_alert_type.ts index ced81098c9f8e..e4ad53de742d6 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/notifications/rules_notification_alert_type.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/notifications/rules_notification_alert_type.ts @@ -45,7 +45,9 @@ export const rulesNotificationAlertType = ({ const ruleParams = { ...ruleAlertParams, name: ruleName, id: ruleAlertSavedObject.id }; const fromInMs = parseScheduleDates( - previousStartedAt ? previousStartedAt.toISOString() : `now-${ruleParams.interval}` + previousStartedAt + ? previousStartedAt.toISOString() + : `now-${ruleAlertSavedObject.attributes.schedule.interval}` )?.format('x'); const toInMs = parseScheduleDates(startedAt.toISOString())?.format('x'); diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/notifications/types.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/notifications/types.ts index 128a7965cd7dc..32a8737adc7c9 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/notifications/types.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/notifications/types.ts @@ -45,10 +45,11 @@ export interface Clients { alertsClient: AlertsClient; } -export type UpdateNotificationParams = Omit & { +export type UpdateNotificationParams = Omit< + NotificationAlertParams, + 'interval' | 'actions' | 'tags' +> & { actions: RuleAlertAction[]; - id?: string; - tags?: string[]; interval: string | null | undefined; ruleAlertId: string; } & Clients; @@ -64,8 +65,6 @@ export interface NotificationAlertParams { ruleAlertId: string; interval: string; name: string; - tags?: string[]; - throttle?: null; } export type CreateNotificationParams = NotificationAlertParams & Clients; diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/notifications/update_notifications.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/notifications/update_notifications.test.ts index 4c077dd9fc1fb..e1f7526438c31 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/notifications/update_notifications.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/notifications/update_notifications.test.ts @@ -9,6 +9,7 @@ import { updateNotifications } from './update_notifications'; import { readNotifications } from './read_notifications'; import { createNotifications } from './create_notifications'; import { getNotificationResult } from '../routes/__mocks__/request_responses'; +import { UpdateNotificationParams } from './types'; jest.mock('./read_notifications'); jest.mock('./create_notifications'); @@ -30,7 +31,6 @@ describe('updateNotifications', () => { enabled: true, interval: '10m', name: '', - tags: [], }); expect(alertsClient.update).toHaveBeenCalledWith( @@ -48,14 +48,13 @@ describe('updateNotifications', () => { it('should create a new notification if did not exist', async () => { (readNotifications as jest.Mock).mockResolvedValue(null); - const params = { + const params: UpdateNotificationParams = { alertsClient, actions: [], ruleAlertId: 'new-rule-id', enabled: true, interval: '10m', name: '', - tags: [], }; await updateNotifications(params); @@ -73,7 +72,6 @@ describe('updateNotifications', () => { enabled: true, interval: null, name: '', - tags: [], }); expect(alertsClient.delete).toHaveBeenCalledWith( @@ -98,7 +96,6 @@ describe('updateNotifications', () => { enabled: true, interval: '10m', name: '', - tags: [], }); expect(alertsClient.update).toHaveBeenCalledWith( @@ -125,10 +122,8 @@ describe('updateNotifications', () => { alertsClient, actions: [], enabled: true, - id: notification.id, ruleAlertId, name: notification.name, - tags: notification.tags, interval: null, }); diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/notifications/update_notifications.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/notifications/update_notifications.ts index 3197d21c0e95a..ac0de406aceb2 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/notifications/update_notifications.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/notifications/update_notifications.ts @@ -15,50 +15,41 @@ export const updateNotifications = async ({ alertsClient, actions, enabled, - id, ruleAlertId, name, - tags, interval, }: UpdateNotificationParams): Promise => { - const notification = await readNotifications({ alertsClient, id, ruleAlertId }); + const notification = await readNotifications({ alertsClient, id: undefined, ruleAlertId }); if (interval && notification) { - const result = await alertsClient.update({ + return alertsClient.update({ id: notification.id, data: { - tags: addTags(tags, ruleAlertId), + tags: addTags([], ruleAlertId), name, schedule: { interval, }, - actions: actions?.map(transformRuleToAlertAction), + actions: actions.map(transformRuleToAlertAction), params: { ruleAlertId, }, throttle: null, }, }); - return result; - } - - if (interval && !notification) { - const result = await createNotifications({ + } else if (interval && !notification) { + return createNotifications({ alertsClient, enabled, - tags, name, interval, actions, ruleAlertId, }); - return result; - } - - if (!interval && notification) { + } else if (!interval && notification) { await alertsClient.delete({ id: notification.id }); return null; + } else { + return null; } - - return null; }; diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/create_rules_bulk_route.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/create_rules_bulk_route.ts index d0e36515946a8..5377e9039785e 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/create_rules_bulk_route.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/create_rules_bulk_route.ts @@ -144,6 +144,7 @@ export const createRulesBulkRoute = (router: IRouter) => { note, version, lists, + actions: throttle === 'rule' ? actions : [], // Only enable actions if throttle is set to rule, otherwise we are a notification and should not enable it, }); const ruleActions = await updateRulesNotifications({ diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/create_rules_route.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/create_rules_route.ts index 6038ad2095323..9a329b78b8f12 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/create_rules_route.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/create_rules_route.ts @@ -132,6 +132,7 @@ export const createRulesRoute = (router: IRouter): void => { note, version: 1, lists, + actions: throttle === 'rule' ? actions : [], // Only enable actions if throttle is rule, otherwise we are a notification and should not enable it, }); const ruleActions = await updateRulesNotifications({ diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/import_rules_route.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/import_rules_route.ts index 43e970702ba72..29ae5056a3ae8 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/import_rules_route.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/import_rules_route.ts @@ -196,6 +196,7 @@ export const importRulesRoute = (router: IRouter, config: LegacyServices['config note, version, lists, + actions: [], // Actions are not imported nor exported at this time }); resolve({ rule_id: ruleId, status_code: 200 }); } else if (rule != null && request.query.overwrite) { diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/update_rules_bulk_route.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/update_rules_bulk_route.ts index 9916972f41843..36e15780f5cb3 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/update_rules_bulk_route.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/update_rules_bulk_route.ts @@ -122,6 +122,7 @@ export const updateRulesBulkRoute = (router: IRouter) => { note, version, lists, + actions, }); if (rule != null) { const ruleActions = await updateRulesNotifications({ diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/update_rules_route.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/update_rules_route.ts index 21dd2a4429cca..0444c757a9b31 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/update_rules_route.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/update_rules_route.ts @@ -118,6 +118,7 @@ export const updateRulesRoute = (router: IRouter) => { note, version, lists, + actions: throttle === 'rule' ? actions : [], // Only enable actions if throttle is rule, otherwise we are a notification and should not enable it }); if (rule != null) { diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rule_actions/create_rule_actions_saved_object.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rule_actions/create_rule_actions_saved_object.ts index 97cfc1d2d9ea7..991690d901d8a 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rule_actions/create_rule_actions_saved_object.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rule_actions/create_rule_actions_saved_object.ts @@ -9,6 +9,7 @@ import { AlertServices } from '../../../../../../../plugins/alerting/server'; import { ruleActionsSavedObjectType } from './saved_object_mappings'; import { IRuleActionsAttributesSavedObjectAttributes } from './types'; import { getThrottleOptions, getRuleActionsFromSavedObject } from './utils'; +import { RulesActionsSavedObject } from './get_rule_actions_saved_object'; interface CreateRuleActionsSavedObject { ruleAlertId: string; @@ -22,12 +23,7 @@ export const createRuleActionsSavedObject = async ({ savedObjectsClient, actions = [], throttle, -}: CreateRuleActionsSavedObject): Promise<{ - id: string; - actions: RuleAlertAction[]; - alertThrottle: string | null; - ruleThrottle: string; -}> => { +}: CreateRuleActionsSavedObject): Promise => { const ruleActionsSavedObject = await savedObjectsClient.create< IRuleActionsAttributesSavedObjectAttributes >(ruleActionsSavedObjectType, { diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rule_actions/delete_rule_actions_saved_object.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rule_actions/delete_rule_actions_saved_object.ts index 864281da5bafd..91489334940bd 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rule_actions/delete_rule_actions_saved_object.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rule_actions/delete_rule_actions_saved_object.ts @@ -18,8 +18,9 @@ export const deleteRuleActionsSavedObject = async ({ savedObjectsClient, }: DeleteRuleActionsSavedObject): Promise<{} | null> => { const ruleActions = await getRuleActionsSavedObject({ ruleAlertId, savedObjectsClient }); - - if (!ruleActions) return null; - - return savedObjectsClient.delete(ruleActionsSavedObjectType, ruleActions.id); + if (ruleActions != null) { + return savedObjectsClient.delete(ruleActionsSavedObjectType, ruleActions.id); + } else { + return null; + } }; diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rule_actions/get_rule_actions_saved_object.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rule_actions/get_rule_actions_saved_object.ts index 61b544db5a18a..dad35f6cb1f96 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rule_actions/get_rule_actions_saved_object.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rule_actions/get_rule_actions_saved_object.ts @@ -15,15 +15,17 @@ interface GetRuleActionsSavedObject { savedObjectsClient: AlertServices['savedObjectsClient']; } -export const getRuleActionsSavedObject = async ({ - ruleAlertId, - savedObjectsClient, -}: GetRuleActionsSavedObject): Promise<{ +export interface RulesActionsSavedObject { id: string; actions: RuleAlertAction[]; alertThrottle: string | null; ruleThrottle: string; -} | null> => { +} + +export const getRuleActionsSavedObject = async ({ + ruleAlertId, + savedObjectsClient, +}: GetRuleActionsSavedObject): Promise => { const { saved_objects } = await savedObjectsClient.find< IRuleActionsAttributesSavedObjectAttributes >({ @@ -35,7 +37,7 @@ export const getRuleActionsSavedObject = async ({ if (!saved_objects[0]) { return null; + } else { + return getRuleActionsFromSavedObject(saved_objects[0]); } - - return getRuleActionsFromSavedObject(saved_objects[0]); }; diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rule_actions/update_or_create_rule_actions_saved_object.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rule_actions/update_or_create_rule_actions_saved_object.ts index adc87150f89a7..d79c61f6200e3 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rule_actions/update_or_create_rule_actions_saved_object.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rule_actions/update_or_create_rule_actions_saved_object.ts @@ -24,16 +24,17 @@ export const updateOrCreateRuleActionsSavedObject = async ({ actions, throttle, }: UpdateOrCreateRuleActionsSavedObject): Promise => { - const currentRuleActions = await getRuleActionsSavedObject({ ruleAlertId, savedObjectsClient }); + const ruleActions = await getRuleActionsSavedObject({ ruleAlertId, savedObjectsClient }); - if (currentRuleActions) { + if (ruleActions != null) { return updateRuleActionsSavedObject({ ruleAlertId, savedObjectsClient, actions, throttle, - }) as Promise; + ruleActions, + }); + } else { + return createRuleActionsSavedObject({ ruleAlertId, savedObjectsClient, actions, throttle }); } - - return createRuleActionsSavedObject({ ruleAlertId, savedObjectsClient, actions, throttle }); }; diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rule_actions/update_rule_actions_saved_object.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rule_actions/update_rule_actions_saved_object.ts index a15005110c56b..2a2c84838ed93 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rule_actions/update_rule_actions_saved_object.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rule_actions/update_rule_actions_saved_object.ts @@ -6,7 +6,7 @@ import { AlertServices } from '../../../../../../../plugins/alerting/server'; import { ruleActionsSavedObjectType } from './saved_object_mappings'; -import { getRuleActionsSavedObject } from './get_rule_actions_saved_object'; +import { RulesActionsSavedObject } from './get_rule_actions_saved_object'; import { RuleAlertAction } from '../../../../common/detection_engine/types'; import { getThrottleOptions } from './utils'; import { IRuleActionsAttributesSavedObjectAttributes } from './types'; @@ -16,6 +16,7 @@ interface DeleteRuleActionsSavedObject { savedObjectsClient: AlertServices['savedObjectsClient']; actions: RuleAlertAction[] | undefined; throttle: string | null | undefined; + ruleActions: RulesActionsSavedObject; } export const updateRuleActionsSavedObject = async ({ @@ -23,16 +24,8 @@ export const updateRuleActionsSavedObject = async ({ savedObjectsClient, actions, throttle, -}: DeleteRuleActionsSavedObject): Promise<{ - ruleThrottle: string; - alertThrottle: string | null; - actions: RuleAlertAction[]; - id: string; -} | null> => { - const ruleActions = await getRuleActionsSavedObject({ ruleAlertId, savedObjectsClient }); - - if (!ruleActions) return null; - + ruleActions, +}: DeleteRuleActionsSavedObject): Promise => { const throttleOptions = throttle ? getThrottleOptions(throttle) : { diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/create_rules.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/create_rules.test.ts index 4c8d0f51f251b..a60f1d4177978 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/create_rules.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/create_rules.test.ts @@ -34,6 +34,7 @@ describe('createRules', () => { interval: '', name: '', tags: [], + actions: [], }); expect(alertsClient.create).toHaveBeenCalledWith( diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/create_rules.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/create_rules.ts index bebf4f350483b..91effb4741b8b 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/create_rules.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/create_rules.ts @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ +import { transformRuleToAlertAction } from '../../../../common/detection_engine/transform_actions'; import { Alert } from '../../../../../../../plugins/alerting/common'; import { APP_ID, SIGNALS_ID } from '../../../../common/constants'; import { CreateRuleParams } from './types'; @@ -42,6 +43,7 @@ export const createRules = async ({ note, version, lists, + actions, }: CreateRuleParams): Promise => { // TODO: Remove this and use regular lists once the feature is stable for a release const listsParam = hasListsFeature() ? { lists } : {}; @@ -81,7 +83,7 @@ export const createRules = async ({ }, schedule: { interval }, enabled, - actions: [], + actions: actions.map(transformRuleToAlertAction), throttle: null, }, }); diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/install_prepacked_rules.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/install_prepacked_rules.ts index bcbe460fb6a66..6d4bacb9cc243 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/install_prepacked_rules.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/install_prepacked_rules.ts @@ -83,6 +83,7 @@ export const installPrepackagedRules = ( note, version, lists, + actions: [], // At this time there is no pre-packaged actions }), ]; }, []); diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/patch_rules.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/patch_rules.ts index d7655a15499eb..5c4889ec5fd68 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/patch_rules.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/patch_rules.ts @@ -120,7 +120,7 @@ export const patchRules = async ({ id: rule.id, data: { tags: addTags(tags ?? rule.tags, rule.params.ruleId, immutable ?? rule.params.immutable), - throttle: rule.throttle, + throttle: null, name: calculateName({ updatedName: name, originalName: rule.name }), schedule: { interval: calculateInterval(interval, rule.schedule.interval), diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/types.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/types.ts index 38b1097a845f8..b1bed5d716155 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/types.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/types.ts @@ -142,12 +142,12 @@ export interface Clients { actionsClient: ActionsClient; } -export type PatchRuleParams = Partial> & { +export type PatchRuleParams = Partial> & { id: string | undefined | null; savedObjectsClient: SavedObjectsClientContract; } & Clients; -export type UpdateRuleParams = Omit & { +export type UpdateRuleParams = Omit & { id: string | undefined | null; savedObjectsClient: SavedObjectsClientContract; } & Clients; @@ -157,7 +157,7 @@ export type DeleteRuleParams = Clients & { ruleId: string | undefined | null; }; -export type CreateRuleParams = Omit & { +export type CreateRuleParams = Omit & { ruleId: string; } & Clients; diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/update_rule_actions.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/update_rule_actions.ts deleted file mode 100644 index e6ee1e6a29764..0000000000000 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/update_rule_actions.ts +++ /dev/null @@ -1,54 +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 { - AlertsClient, - AlertServices, - PartialAlert, -} from '../../../../../../../plugins/alerting/server'; -import { getRuleActionsSavedObject } from '../rule_actions/get_rule_actions_saved_object'; -import { readRules } from './read_rules'; -import { transformRuleToAlertAction } from '../../../../common/detection_engine/transform_actions'; - -interface UpdateRuleActions { - alertsClient: AlertsClient; - savedObjectsClient: AlertServices['savedObjectsClient']; - ruleAlertId: string; -} - -export const updateRuleActions = async ({ - alertsClient, - savedObjectsClient, - ruleAlertId, -}: UpdateRuleActions): Promise => { - const rule = await readRules({ alertsClient, id: ruleAlertId }); - if (rule == null) { - return null; - } - - const ruleActions = await getRuleActionsSavedObject({ - savedObjectsClient, - ruleAlertId, - }); - - if (!ruleActions) { - return null; - } - - return alertsClient.update({ - id: ruleAlertId, - data: { - actions: !ruleActions.alertThrottle - ? ruleActions.actions.map(transformRuleToAlertAction) - : [], - throttle: null, - name: rule.name, - tags: rule.tags, - schedule: rule.schedule, - params: rule.params, - }, - }); -}; diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/update_rules.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/update_rules.test.ts index ca299db6ace50..72f4cbcbe68e8 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/update_rules.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/update_rules.test.ts @@ -35,6 +35,7 @@ describe('updateRules', () => { interval: '', name: '', tags: [], + actions: [], }); expect(alertsClient.disable).toHaveBeenCalledWith( @@ -61,6 +62,7 @@ describe('updateRules', () => { interval: '', name: '', tags: [], + actions: [], }); expect(alertsClient.enable).toHaveBeenCalledWith( @@ -89,6 +91,7 @@ describe('updateRules', () => { interval: '', name: '', tags: [], + actions: [], }); expect(alertsClient.update).toHaveBeenCalledWith( diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/update_rules.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/update_rules.ts index 0e70e05f4de78..99326768ed33b 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/update_rules.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/update_rules.ts @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ +import { transformRuleToAlertAction } from '../../../../common/detection_engine/transform_actions'; import { PartialAlert } from '../../../../../../../plugins/alerting/server'; import { readRules } from './read_rules'; import { IRuleSavedAttributesSavedObjectAttributes, UpdateRuleParams } from './types'; @@ -46,6 +47,7 @@ export const updateRules = async ({ lists, anomalyThreshold, machineLearningJobId, + actions, }: UpdateRuleParams): Promise => { const rule = await readRules({ alertsClient, ruleId, id }); if (rule == null) { @@ -90,8 +92,8 @@ export const updateRules = async ({ tags: addTags(tags, rule.params.ruleId, rule.params.immutable), name, schedule: { interval }, - actions: rule.actions, - throttle: rule.throttle, + actions: actions.map(transformRuleToAlertAction), + throttle: null, params: { description, ruleId: rule.params.ruleId, diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/update_rules_notifications.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/update_rules_notifications.ts index bb66a5ee1342f..994a54048b71a 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/update_rules_notifications.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/update_rules_notifications.ts @@ -8,7 +8,6 @@ import { RuleAlertAction } from '../../../../common/detection_engine/types'; import { AlertsClient, AlertServices } from '../../../../../../../plugins/alerting/server'; import { updateOrCreateRuleActionsSavedObject } from '../rule_actions/update_or_create_rule_actions_saved_object'; import { updateNotifications } from '../notifications/update_notifications'; -import { updateRuleActions } from './update_rule_actions'; import { RuleActions } from '../rule_actions/types'; interface UpdateRulesNotifications { @@ -37,19 +36,13 @@ export const updateRulesNotifications = async ({ throttle, }); - await updateRuleActions({ - alertsClient, - savedObjectsClient, - ruleAlertId, - }); - await updateNotifications({ alertsClient, ruleAlertId, enabled, name, actions: ruleActions.actions, - interval: ruleActions?.alertThrottle, + interval: ruleActions.alertThrottle, }); return ruleActions; diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/types.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/types.ts index d4469351de544..040e32aa0d360 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/types.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/types.ts @@ -162,5 +162,10 @@ export interface AlertAttributes { } export interface RuleAlertAttributes extends AlertAttributes { - params: Omit & { ruleId: string }; + params: Omit< + RuleAlertParams, + 'ruleId' | 'name' | 'enabled' | 'interval' | 'tags' | 'actions' | 'throttle' + > & { + ruleId: string; + }; } From 274cb805e1ed5138b0e0cd285aa9d420be5ce2b4 Mon Sep 17 00:00:00 2001 From: "Devin W. Hurley" Date: Wed, 8 Apr 2020 19:58:50 -0400 Subject: [PATCH 38/40] =?UTF-8?q?[SIEM]=20[Detection=20Engine]=20Fixes=20b?= =?UTF-8?q?ug=20when=20notification=20doesn't=E2=80=A6=20(#63013)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Set refresh on bulk create to 'wait_for' when actions are present, so we do not respond until the newly indexed signals are searchable. * set refresh on bulk create to 'wait_for' when actions are present, so we do not respond until the newly indexed signals are searchable * fix types in tests --- .../signals/bulk_create_ml_signals.ts | 3 +- .../signals/search_after_bulk_create.test.ts | 8 +++++ .../signals/search_after_bulk_create.ts | 6 +++- .../signals/signal_rule_alert_type.test.ts | 32 +++++++++++++++++++ .../signals/signal_rule_alert_type.ts | 3 ++ .../signals/single_bulk_create.test.ts | 6 ++++ .../signals/single_bulk_create.ts | 6 ++-- .../siem/server/lib/detection_engine/types.ts | 2 ++ 8 files changed, 62 insertions(+), 4 deletions(-) diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/bulk_create_ml_signals.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/bulk_create_ml_signals.ts index 355041d9efbdb..ba8938f116fc6 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/bulk_create_ml_signals.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/bulk_create_ml_signals.ts @@ -10,7 +10,7 @@ import { SearchResponse } from 'elasticsearch'; import { Logger } from '../../../../../../../../src/core/server'; import { AlertServices } from '../../../../../../../plugins/alerting/server'; import { RuleAlertAction } from '../../../../common/detection_engine/types'; -import { RuleTypeParams } from '../types'; +import { RuleTypeParams, RefreshTypes } from '../types'; import { singleBulkCreate, SingleBulkCreateResponse } from './single_bulk_create'; import { AnomalyResults, Anomaly } from '../../machine_learning'; @@ -29,6 +29,7 @@ interface BulkCreateMlSignalsParams { updatedBy: string; interval: string; enabled: boolean; + refresh: RefreshTypes; tags: string[]; throttle: string; } diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/search_after_bulk_create.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/search_after_bulk_create.test.ts index 414270ffcdd5c..81600b0b8dd9b 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/search_after_bulk_create.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/search_after_bulk_create.test.ts @@ -52,6 +52,7 @@ describe('searchAfterAndBulkCreate', () => { enabled: true, pageSize: 1, filter: undefined, + refresh: false, tags: ['some fake tag 1', 'some fake tag 2'], throttle: 'no_actions', }); @@ -126,6 +127,7 @@ describe('searchAfterAndBulkCreate', () => { enabled: true, pageSize: 1, filter: undefined, + refresh: false, tags: ['some fake tag 1', 'some fake tag 2'], throttle: 'no_actions', }); @@ -156,6 +158,7 @@ describe('searchAfterAndBulkCreate', () => { enabled: true, pageSize: 1, filter: undefined, + refresh: false, tags: ['some fake tag 1', 'some fake tag 2'], throttle: 'no_actions', }); @@ -198,6 +201,7 @@ describe('searchAfterAndBulkCreate', () => { enabled: true, pageSize: 1, filter: undefined, + refresh: false, tags: ['some fake tag 1', 'some fake tag 2'], throttle: 'no_actions', }); @@ -240,6 +244,7 @@ describe('searchAfterAndBulkCreate', () => { enabled: true, pageSize: 1, filter: undefined, + refresh: false, tags: ['some fake tag 1', 'some fake tag 2'], throttle: 'no_actions', }); @@ -284,6 +289,7 @@ describe('searchAfterAndBulkCreate', () => { enabled: true, pageSize: 1, filter: undefined, + refresh: false, tags: ['some fake tag 1', 'some fake tag 2'], throttle: 'no_actions', }); @@ -328,6 +334,7 @@ describe('searchAfterAndBulkCreate', () => { enabled: true, pageSize: 1, filter: undefined, + refresh: false, tags: ['some fake tag 1', 'some fake tag 2'], throttle: 'no_actions', }); @@ -374,6 +381,7 @@ describe('searchAfterAndBulkCreate', () => { enabled: true, pageSize: 1, filter: undefined, + refresh: false, tags: ['some fake tag 1', 'some fake tag 2'], throttle: 'no_actions', }); diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/search_after_bulk_create.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/search_after_bulk_create.ts index ff81730bc4a72..3a964cb91fbdb 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/search_after_bulk_create.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/search_after_bulk_create.ts @@ -6,7 +6,7 @@ import { AlertServices } from '../../../../../../../plugins/alerting/server'; import { RuleAlertAction } from '../../../../common/detection_engine/types'; -import { RuleTypeParams } from '../types'; +import { RuleTypeParams, RefreshTypes } from '../types'; import { Logger } from '../../../../../../../../src/core/server'; import { singleSearchAfter } from './single_search_after'; import { singleBulkCreate } from './single_bulk_create'; @@ -30,6 +30,7 @@ interface SearchAfterAndBulkCreateParams { enabled: boolean; pageSize: number; filter: unknown; + refresh: RefreshTypes; tags: string[]; throttle: string; } @@ -61,6 +62,7 @@ export const searchAfterAndBulkCreate = async ({ interval, enabled, pageSize, + refresh, tags, throttle, }: SearchAfterAndBulkCreateParams): Promise => { @@ -92,6 +94,7 @@ export const searchAfterAndBulkCreate = async ({ updatedBy, interval, enabled, + refresh, tags, throttle, }); @@ -179,6 +182,7 @@ export const searchAfterAndBulkCreate = async ({ updatedBy, interval, enabled, + refresh, tags, throttle, }); diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/signal_rule_alert_type.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/signal_rule_alert_type.test.ts index 3d6f443ce60d6..03fb5832fdf42 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/signal_rule_alert_type.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/signal_rule_alert_type.test.ts @@ -105,6 +105,7 @@ describe('rules_notification_alert_type', () => { }; (ruleStatusServiceFactory as jest.Mock).mockReturnValue(ruleStatusService); (getGapBetweenRuns as jest.Mock).mockReturnValue(moment.duration(0)); + (searchAfterAndBulkCreate as jest.Mock).mockClear(); (searchAfterAndBulkCreate as jest.Mock).mockResolvedValue({ success: true, searchAfterTimes: [], @@ -149,6 +150,37 @@ describe('rules_notification_alert_type', () => { }); }); + it("should set refresh to 'wait_for' when actions are present", async () => { + const ruleAlert = getResult(); + ruleAlert.actions = [ + { + actionTypeId: '.slack', + params: { + message: + 'Rule generated {{state.signals_count}} signals\n\n{{context.rule.name}}\n{{{context.results_link}}}', + }, + group: 'default', + id: '99403909-ca9b-49ba-9d7a-7e5320e68d05', + }, + ]; + + savedObjectsClient.get.mockResolvedValue({ + id: 'id', + type: 'type', + references: [], + attributes: ruleAlert, + }); + await alert.executor(payload); + expect((searchAfterAndBulkCreate as jest.Mock).mock.calls[0][0].refresh).toEqual('wait_for'); + (searchAfterAndBulkCreate as jest.Mock).mockClear(); + }); + + it('should set refresh to false when actions are not present', async () => { + await alert.executor(payload); + expect((searchAfterAndBulkCreate as jest.Mock).mock.calls[0][0].refresh).toEqual(false); + (searchAfterAndBulkCreate as jest.Mock).mockClear(); + }); + it('should call scheduleActions if signalsCount was greater than 0 and rule has actions defined', async () => { const ruleAlert = getResult(); ruleAlert.actions = [ diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/signal_rule_alert_type.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/signal_rule_alert_type.ts index faac4a547fc17..0357f906f8035 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/signal_rule_alert_type.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/signal_rule_alert_type.ts @@ -98,6 +98,7 @@ export const signalRulesAlertType = ({ params: ruleParams, } = savedObject.attributes; const updatedAt = savedObject.updated_at ?? ''; + const refresh = actions.length ? 'wait_for' : false; const buildRuleMessage = buildRuleMessageFactory({ id: alertId, ruleId, @@ -181,6 +182,7 @@ export const signalRulesAlertType = ({ updatedAt, interval, enabled, + refresh, tags, }); result.success = success; @@ -241,6 +243,7 @@ export const signalRulesAlertType = ({ interval, enabled, pageSize: searchAfterSize, + refresh, tags, throttle, }); diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/single_bulk_create.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/single_bulk_create.test.ts index 56f061cdfa3ca..45365b446cbf0 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/single_bulk_create.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/single_bulk_create.test.ts @@ -159,6 +159,7 @@ describe('singleBulkCreate', () => { updatedBy: 'elastic', interval: '5m', enabled: true, + refresh: false, tags: ['some fake tag 1', 'some fake tag 2'], throttle: 'no_actions', }); @@ -192,6 +193,7 @@ describe('singleBulkCreate', () => { updatedBy: 'elastic', interval: '5m', enabled: true, + refresh: false, tags: ['some fake tag 1', 'some fake tag 2'], throttle: 'no_actions', }); @@ -217,6 +219,7 @@ describe('singleBulkCreate', () => { updatedBy: 'elastic', interval: '5m', enabled: true, + refresh: false, tags: ['some fake tag 1', 'some fake tag 2'], throttle: 'no_actions', }); @@ -243,6 +246,7 @@ describe('singleBulkCreate', () => { updatedBy: 'elastic', interval: '5m', enabled: true, + refresh: false, tags: ['some fake tag 1', 'some fake tag 2'], throttle: 'no_actions', }); @@ -271,6 +275,7 @@ describe('singleBulkCreate', () => { updatedBy: 'elastic', interval: '5m', enabled: true, + refresh: false, tags: ['some fake tag 1', 'some fake tag 2'], throttle: 'no_actions', }); @@ -365,6 +370,7 @@ describe('singleBulkCreate', () => { updatedBy: 'elastic', interval: '5m', enabled: true, + refresh: false, tags: ['some fake tag 1', 'some fake tag 2'], throttle: 'no_actions', }); diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/single_bulk_create.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/single_bulk_create.ts index 6dd8823b57e4d..fc33d0e15e43f 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/single_bulk_create.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/single_bulk_create.ts @@ -9,7 +9,7 @@ import { performance } from 'perf_hooks'; import { AlertServices } from '../../../../../../../plugins/alerting/server'; import { SignalSearchResponse, BulkResponse } from './types'; import { RuleAlertAction } from '../../../../common/detection_engine/types'; -import { RuleTypeParams } from '../types'; +import { RuleTypeParams, RefreshTypes } from '../types'; import { generateId, makeFloatString } from './utils'; import { buildBulkBody } from './build_bulk_body'; import { Logger } from '../../../../../../../../src/core/server'; @@ -31,6 +31,7 @@ interface SingleBulkCreateParams { enabled: boolean; tags: string[]; throttle: string; + refresh: RefreshTypes; } /** @@ -77,6 +78,7 @@ export const singleBulkCreate = async ({ updatedBy, interval, enabled, + refresh, tags, throttle, }: SingleBulkCreateParams): Promise => { @@ -124,7 +126,7 @@ export const singleBulkCreate = async ({ const start = performance.now(); const response: BulkResponse = await services.callCluster('bulk', { index: signalsIndex, - refresh: false, + refresh, body: bulkBody, }); const end = performance.now(); diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/types.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/types.ts index d3fa98fd73d3a..035f1b10ff8b2 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/types.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/types.ts @@ -149,3 +149,5 @@ export type CallWithRequest, V> = ( params: T, options?: CallAPIOptions ) => Promise; + +export type RefreshTypes = false | 'wait_for'; From 82e048a5fb57de3afd309e301536a90971edd7de Mon Sep 17 00:00:00 2001 From: Joe Reuter Date: Thu, 9 Apr 2020 09:28:44 +0200 Subject: [PATCH 39/40] add embed flag to saved object url as well (#62926) --- src/plugins/share/public/components/url_panel_content.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/plugins/share/public/components/url_panel_content.tsx b/src/plugins/share/public/components/url_panel_content.tsx index 2b77b6f4592a8..2b1159be89003 100644 --- a/src/plugins/share/public/components/url_panel_content.tsx +++ b/src/plugins/share/public/components/url_panel_content.tsx @@ -166,7 +166,7 @@ export class UrlPanelContent extends Component { // Get the application route, after the hash, and remove the #. const parsedAppUrl = parseUrl(parsedUrl.hash.slice(1), true); - return formatUrl({ + let formattedUrl = formatUrl({ protocol: parsedUrl.protocol, auth: parsedUrl.auth, host: parsedUrl.host, @@ -180,6 +180,11 @@ export class UrlPanelContent extends Component { }, }), }); + if (this.props.isEmbedded) { + formattedUrl = this.makeUrlEmbeddable(url); + } + + return formattedUrl; }; private getSnapshotUrl = () => { From 7b0e9d00aafa995c4a6261be7a1446362647e170 Mon Sep 17 00:00:00 2001 From: Robert Oskamp Date: Thu, 9 Apr 2020 11:43:51 +0200 Subject: [PATCH 40/40] [ML] Functional transform tests - stabilize source selection (#63087) This PR adds a retry to the transform source selection service method for functional tests. --- .../functional/services/transform_ui/source_selection.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/x-pack/test/functional/services/transform_ui/source_selection.ts b/x-pack/test/functional/services/transform_ui/source_selection.ts index d2ef2c67f0004..38a819e285d67 100644 --- a/x-pack/test/functional/services/transform_ui/source_selection.ts +++ b/x-pack/test/functional/services/transform_ui/source_selection.ts @@ -8,6 +8,7 @@ import { FtrProviderContext } from '../../ftr_provider_context'; export function TransformSourceSelectionProvider({ getService }: FtrProviderContext) { const testSubjects = getService('testSubjects'); + const retry = getService('retry'); return { async assertSourceListContainsEntry(sourceName: string) { @@ -23,8 +24,10 @@ export function TransformSourceSelectionProvider({ getService }: FtrProviderCont async selectSource(sourceName: string) { await this.filterSourceSelection(sourceName); - await testSubjects.clickWhenNotDisabled(`savedObjectTitle${sourceName}`); - await testSubjects.existOrFail('transformPageCreateTransform'); + await retry.tryForTime(30 * 1000, async () => { + await testSubjects.clickWhenNotDisabled(`savedObjectTitle${sourceName}`); + await testSubjects.existOrFail('transformPageCreateTransform', { timeout: 10 * 1000 }); + }); }, }; }

&%3;cZTYaU}5&3LV*?qDac`_MRlIDB- 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