Merge remote-tracking branch 'origin/master' into feature/merge-code

This commit is contained in:
Fuyao Zhao 2019-02-08 17:43:45 -08:00
commit d3ceee5cf1
2533 changed files with 113781 additions and 39087 deletions

View file

@ -1,5 +1,5 @@
{
"upstream": "elastic/kibana",
"branches": [{ "name": "6.x", "checked": true }, "6.6", "6.5", "6.4", "6.3", "6.2", "6.1", "6.0", "5.6"],
"branches": [{ "name": "7.x", "checked": true }, "7.0", "6.7", "6.6", "6.5", "6.4", "6.3", "6.2", "6.1", "6.0", "5.6"],
"labels": ["backport"]
}

View file

@ -25,7 +25,7 @@ bower_components
/packages/kbn-ui-framework/dist
/packages/kbn-ui-framework/doc_site/build
/packages/kbn-ui-framework/generator-kui/*/templates/
/x-pack/plugins/gis/public/vendor/**
/x-pack/plugins/maps/public/vendor/**
/x-pack/coverage
/x-pack/build
/x-pack/plugins/**/__tests__/fixtures/**

View file

@ -331,7 +331,7 @@ module.exports = {
* GIS overrides
*/
{
files: ['x-pack/plugins/gis/**/*'],
files: ['x-pack/plugins/maps/**/*'],
rules: {
'react/prefer-stateless-function': [0, { ignorePureComponents: false }],
},

4
.github/CODEOWNERS vendored
View file

@ -11,9 +11,13 @@
# Canvas
/x-pack/plugins/canvas/ @elastic/kibana-canvas
# Machine Learning
/x-pack/plugins/ml/ @elastic/ml-ui
# Security
/x-pack/plugins/security/ @elastic/kibana-security
/x-pack/plugins/spaces/ @elastic/kibana-security
/src/server/csp/ @elastic/kibana-security
# Design
**/*.scss @elastic/kibana-design

View file

@ -3,6 +3,7 @@
"common.ui": "src/ui",
"server": "src/server",
"console": "src/legacy/core_plugins/console",
"core": "src/core",
"inputControl": "src/legacy/core_plugins/input_control_vis",
"inspectorViews": "src/legacy/core_plugins/inspector_views",
"interpreter": "src/legacy/core_plugins/interpreter",
@ -45,6 +46,7 @@
"xpack.watcher": "x-pack/plugins/watcher"
},
"exclude": [
"src/core/public/fatal_errors/get_error_info.ts",
"src/ui/ui_render/bootstrap/app_bootstrap.js",
"src/ui/ui_render/ui_render_mixin.js",
"x-pack/plugins/infra/public/graphql/types.ts",

View file

@ -1 +1 @@
10.14.1
10.15.1

2
.nvmrc
View file

@ -1 +1 @@
10.14.1
10.15.1

View file

@ -21,4 +21,4 @@ if [ ! -x "$NODE" ]; then
exit 1
fi
NODE_ENV=production exec "${NODE}" $NODE_OPTIONS --no-warnings "${DIR}/src/cli" ${@}
NODE_ENV=production exec "${NODE}" --no-warnings --max-http-header-size=65536 $NODE_OPTIONS "${DIR}/src/cli" ${@}

View file

@ -14,7 +14,7 @@ If Not Exist "%NODE%" (
Exit /B 1
)
"%NODE%" %NODE_OPTIONS% --no-warnings "%DIR%\src\cli" %*
"%NODE%" --no-warnings --max-http-header-size=65536 %NODE_OPTIONS% "%DIR%\src\cli" %*
:finally

View file

@ -13,372 +13,12 @@
This section summarizes the changes in each release.
* <<release-notes-7.0.0-alpha2>>
* <<release-notes-7.0.0-alpha1>>
* <<release-notes-8.0.0-alpha1>>
--
[[release-notes-7.0.0-alpha2]]
== {kib} 7.0.0-alpha2
[float]
[[breaking-7.0.0-alpha2]]
=== Breaking changes
For more details about breaking changes in this release, see
<<breaking-changes-7.0, Breaking changes in 7.0>>.
[float]
[[highlight-7.0.0-alpha2]]
=== Highlights
Canvas::
* Canvas now has a template tab in the workpad manager where users can find workpad templates,
demos, and tutorials to help them get started. See {pull}23966[#23966] for more information.
Kibana App::
* Visualizations in Kibana will use a new data pipeline introduced as part of Canvas.
The change does not yet apply to Vega, Timelion, or Time Series Visual Builder (TSVB).
See {pull}25711[#25711] for more information.
Index Lifecyle Management::
* Implements a user interface to create, update, edit, or delete index lifecyle policies.
See {pull}25553[#25553] for more information.
[float]
[[enhancement-7.0.0-alpha2]]
=== Enhancements
Canvas::
* Implements a clipboard and stores the copied elements in `localStorage` {pull}25890[#25890]
* Adds the ability to reuse assets without editing an element's expression {pull}25764[#25764]
* Adds the `clear` function {pull}26397[#26397]
* Adds workpad-level CSS {pull}24143[#24143]
Dashboard::
* Adds `href` option in addition to `onClick` for navigational links {pull}25233[#25233]
Design::
* Updates logos for marketing {pull}25489[#25489]
* Adds Kibana 7.0 breadcrumbs to home screen {pull}26605[#26605]
* Moves elastic/eui typings to single file {pull}23950[#23950]
Kibana App::
* Maps inspector requests by id so single requests can be reset at a time {pull}26770[#26770]
* Adds ODBC to blurb for start trail {pull}27223[#27223]
Management::
* Adds `Request timestamp` to request inspector stats {pull}25667[#25667]
* Adds "Reload indices" button to Index Management {pull}27033[#27033]
Machine Learning::
* Adds the configuration files for two new auditbeat data recognizer modules for
detecting unusual processes on hosts and Docker containers {pull}25716[#25716]
* Adds support for saved searches created using Kuery to the job wizards {pull}26094[#26094]
* Allows users to enter their own query in the Discover page; stops passing the query
from the job datafeed config in custom URLs {pull}26957[#26957]
* Rewrites Calendar to React/EUI {pull}26741[#26741]
* Converts Setting page to React/EUI {pull}27144[#27144]
* Ensures loading indicator is present on initial jobs load {pull}27151[#27151]
* Prevents a new calendar save if a calendar with that id already exists {pull}27104[#27104]
Observability::
* Adds a new plugin for Uptime Monitoring {pull}25480[#25480]
Platform::
* Adds `rest_total_hits_as_int` to all requests in platform code that eventually
look up `hits.total` {pull}26432[#26432]
* Adds `dist` flag to the configuration context {pull}26545[#26545]
* Prepares `@kbn/datemath` to be republished as `@elastic/datemath` {pull}26559[#26559]
* Wraps `remote` methods in `browser` service {pull}26394[#26394]
* Uses `stream.pipeline` to manage error handling {pull}27246[#27246]
Querying & Filtering::
* Moves the `buildESQuery` module (including filters and Kuery) into a separate package {pull}23345[#23345]
* Adds comment explaining why `getComputedFields` adds a `docvalue` to `docvalue_fields`
for each date field in an index pattern. {pull}25725[#25725]
* Moves filtering functions out of `vis.API.events` {pull}25280[#25280]
Reporting::
* Adds browser type to the reporting side panel {pull}26307[#26307]
* Adds better logging for `waitForSelector` failure {pull}25762[#25762]
* Enhances error messaging and handling {pull}26299[#26299]
* Adds "Info" button in the Reporting listing {pull}25421[#25421]
Rollups::
* Adds support for rolling up metrics of date fields {pull}26450[#26450]
Security::
* Updates the GET `/api/security/role` endpoint to return the list of roles sorted
by name, rather than creation date {pull}26491[#26491]
* Updates the Account Settings screen to show the change password form only when
a password change is possible for the authentication realm {pull}26779[#26779]
* Makes space selector a `button` {pull}26889[#26889]
Visualizations::
* Removes experimental flag from Visual Builder (TSVB) {pull}25634[#25634]
* Implements new visualization type selection {pull}23833[#23833]
* Removes `lab` stage for visualizations, making `experimental` the only non-production
stage available {pull}25702[#25702]
[float]
[[bug-7.0.0-alpha2]]
=== Bug fixes
Canvas::
* Fixes page preview size issue {pull}26795[#26795]
* Fixes visual bug when opening the workpad loader {pull}26647[#26647]
* Fixes page thumbnail sizes {pull}26573[#26573]
* Decreases size of tray toggle {pull}25470[#25470]
* Makes selection border 1px {pull}26739[#26739]
* Fixes interpreter socket error {pull}26870[#26870]
Geo::
* Resolves URL dynamically when requesting EMS data {pull}25685[#25685]
* Fixes EMS hotlink {pull}26868[#26868]
Infrastructure UI::
* Fixes potential color bugs {pull}26292[#26292]
* Fixes auto refresh button on node detail page {pull}26426[#26426]
* Changes the time range from the last hour to the last 5 minutes for the Waffle Map {pull}26278[#26278]
* Passes flag in request to force BWC hit count {pull}26517[#26517]
* Replaces redux source slice with constate container {pull}26121[#26121]
* Changes node detail link to set time range to 1 hour {pull}26977[#26977]
* Stops showing sidenav while loading. {pull}27119[#27119]
* Fixes styling after breaking EUI changes {pull}27021[#27021]
* Fixes graphql type generation after package upgrades {pull}26991[#26991]
* Removes usage of `ts-optchain` in the browser {pull}27148[#27148]
Kibana App::
* Fixes support for React 16.4+ by only resetting state if adaptors are updated {pull}26138[#26138]
* Fixes scrolling list on Firefox {pull}26246[#26246]
* Guards against empty and undefined index pattern arrays passed to QueryBar {pull}24607[#24607]
* Removes unused indexPattern from vega/tsvb/timelion request handler {pull}26007[#26007]
* Passes global filters from editor down to visualize {pull}26009[#26009]
* Stops using schemas in aggconfigs to output DSL {pull}26010[#26010]
* Fixes `kbn-interpreter` package to not import from UI {pull}26161[#26161]
* Fixes OSS dynamic plugin loading by reverting to Canvas way of loading plugins {pull}26463[#26463]
* Fixes other bucket option to correctly apply without having to change other settings {pull}26874[#26874]
* Adds `en` as a valid numeral locale setting {pull}25948[#25948]
* Adds `rest_total_hits_as_int` into Kibana App {pull}26404[#26404]
* Uses Canvas pipeline to fetch data inside Visualize {pull}25996[#25996]
Management::
* Fixes index pattern wizard when there are remote clusters but no local indices {pull}24339[#24339]
* Uses new `_graph` endpoints {pull}26956[#26956]
* Adjusts spacing of Management navigation items {pull}25666[#25666]
* Updates "Disenroll" text to be consistent with menu option "Unenroll" {pull}26816[#26816]
* Fixes broken breadcrumb link for index management {pull}27164[#27164]
* Fixes issue with multiple execution in Console {pull}26933[#26933]
* Reloads full index list when reload hits missing index {pull}27197[#27197]
Machine Learning::
* Allows user to add/edit/delete annotations in the Single Series Viewer {pull}26034[#26034]
* Does not pass datafeed query to Discover in custom URL {pull}26957[#26957]
* Fixes word break in Anomalies and Jobs tables {pull}26978[#26978]
* Fixes alignment of filter icons in the Anomalies table {pull}26253[#26253]
Monitoring::
* Fixes error handling for local stats collection/permissions {pull}26560[#26560]
* Removes initial delay to check and send Telemetry data {pull}26575[#26575]
* Pulls local Kibana usage stats {pull}26496[#26496]
* Converts the Elasticsearch monitoring UIs to using EUI tables and page layout {pull}26217[#26217]
Platform & Operations::
* Decreases start limit and interval {pull}25474[#25474]
* Adds `--download` flag to snapshot command to warm the cache {pull}25830[#25830]
* Implements `--prefer-offline` flag {pull}25840[#25840]
* Fixes watcher routes broken by Hapi upgrade {pull}26713[#26713]
* Fixes non-conforming licenses on devDependencies and adds the ability to whitelist devOnly licenses {pull}23859[#23859]
* Watches optimizer cache invalidation {pull}24172[#24172]
* Adds `normalizePath` in order to fix watch optimizer when running on Windows {pull}26486[#26486]
* Creates vendor dll for the client modules {pull}22618[#22618]
* Upgrades to NodeJS 10 {pull}25157[#25157]
* Improves plugin version mismatch error message {pull}25774[#25774]
* Improves build/packaging {pull}26096[#26096]
* Swaps `jstimezonedetect` with `moment.tz.guess` {pull}21800[#21800]
* Upgrades resize-observer-polyfill version {pull}26990[#26990]
* Fixes saved objects client `_processBatchQueue` function to handle errors {pull}26763[#26763]
* Changes kbn pm webpack config to generate dist files in mode=none {pull}26847[#26847]
* Hides logs from deleteAll on task: clean client modules into dll {pull}26884[#26884]
* Upgrades `resize-observer-polyfill` version {pull}26990[#26990]
* Uses `single-node` discovery type for the test ES node/cluster {pull}27125[#27125]
* Moves moment to peerDependency in elastic-datemath {pull}27264[#27264]
Reporting::
* Deletes `sortOrder` once items have been sorted and does not pass to `EuiContextMenuItem`
in the share context menu {pull}26890[#26890]
* Fixes a regression bug in detection of Error and Warning toast notifications {pull}25482[#25482]
* Stops passing an empty `formatConfig` to the fieldFormats helper {pull}27168[#27168]
Rollups::
* Shows loading state in Rollup Job detail panel. {pull}25752[#25752]
* Specifies Rollup Jobs breadcrumbs in header. {pull}26590[#26590]
* Requires histogram interval in Rollup Job wizard to be a whole number. {pull}26596[#26596]
Security::
* Moves the server-side `SavedObjectClient` types from the `spaces` plugin to the
same location as the corresponding JavaScript source files {pull}26448[#26448]
* Respects the `basePath` for the link to the user profile in the k7 header {pull}26417[#26417]
* Fixes `prettier` throw rule error {pull}26071[#26071]
* Fixes authentication logic to fail out of auth flow on first provider failure {pull}26648[#26648]
* Fixes issues with the `url.search` being null in Node 10 {pull}26992[#26992]
* Fixes DLS query toggle on the role management page {pull}27213[#27213]
Visualizations::
* Fixes filter function on pie chart segment {pull}26321[#26321]
* Rewrites URL when closing vis type selection modal {pull}26327[#26327]
* Changes unbind calls from `.on` to `.off` {pull}24575[#24575]
* Fixes date field in controls visualization by generating labels with the field
formatter {pull}25654[#25654]
* Replaces LESS files with Sass in `ui/public/vis`, `visLib`, and `visualize` {pull}25333[#25333]
* Replaces LESS files with Sass for the visualization types in `core_plugin/metrics` {pull}24250[#24250]
* Moves `timeout` to `_msearch` body to fix time series visual builder requests {pull}26510[#26510]
* Adds description for all visualization types {pull}26243[#26243]
[[release-notes-7.0.0-alpha1]]
== {kib} 7.0.0-alpha1
[float]
[[breaking-7.0.0]]
=== Breaking changes
For more details about breaking changes in this release, see
<<breaking-changes-7.0, Breaking changes in 7.0>>.
Discover::
* Does not apply `query:queryString:options` to `query_string` filters {pull}15640[#15640]
* Removes `default_field` from `query:queryString:options` {pull}18966[#18966]
Monitoring::
* Removes `node_resolver` setting {pull}21181[#21181]
Operations::
* Removes tribe node support {pull}16397[#16397]
* Creates separate startup scripts for development and production {pull}13806[#13806]
* Sets default port based on protocol {pull}21564[#21564]
* Removes deprecated `/shorten` API {pull}21861[#21861]
* Plugin installer defers optimization step until server start {pull}26983[#26983]
[float]
[[deprecation-7.0.0]]
=== Deprecations
Geo::
* Fixes legacy tilemap loading {pull}22095[#22095]
[float]
[[K7-design-7.0.0]]
=== K7 UI Design
{kib} 7.0.0-alpha1 includes a new design for {kib} called K7. In this early stage,
K7 is still a little rough around the edges. If you'd like to switch back to the
existing K6 design, go to *Management > Advanced Settings* and turn
off the *k7design* setting. The option to switch to the old design
will be removed before 7.0.0 GA.
[float]
[[enhancement-7.0.0]]
=== Enhancements
Machine Learning::
* Updates job type and APM module icon to new designs {pull}25380[#25380]
* Allows model plot enablement via checkbox in MultiMetric/Population Job creation {pull}24914[#24914]
* Adds support for the rare detector for charts in Anomaly Explorer and Singe Metric viewer {pull}21524[#21524]
Reporting::
* Adds png output to reports {pull}24759[#24759]
* Sorts ascending on sort order first then ascending on name. Any menu item
without a sort order gets set to zero. {pull}25058[#25058]
Visualizations::
* Adds a console.error for visualize errors {pull}24581[#24581]
[float]
[[bug-7.0.0]]
=== Bug fixes
APM::
* Overrides EUI chart default styles for gridlines {pull}21723[#21723]
* Adds section titles to span detail modal {pull}20717[#20717]
Canvas::
* Fixes duplicate `Value` options in math select value {pull}25556[#25556]
* Gets correct plugins path {pull}25448[#25448]
* Quotes the index pattern in SQL input {pull}25488[#25488]
* Decreases the size of tray toggle {pull}25470[#25470]
* Improves the plugin pre-build {pull}25267[#25267]
Dashboard::
* Removes `dashboardContext` function and makes Timelion, Vega, and Time Series
Visual Builder use `buildEsQuery` {pull}23227[#23227]
Design::
* Converts Security UI from LESS to Sass {pull}25079[#25079]
* Adds boilerplate Sass for Kibana core {pull}21185[#21185]
Discover::
* Adds debug code to flaky field_data test {pull}15535[#15535]
* Gets even more debug info for flaky field_data test {pull}17627[#17627]
Geo::
* Fixes feature/align map config settings {pull}19450[#19450]
Kibana App::
* Adds warning to the `documentation_links` file about link validation gotcha {pull}24786[#24786]
* Adds workaround for `getDerivedStateFromProps` change in react 16.4 {pull}25142[#25142]
Kibana Home &amp; Add Data::
* Fixes "Set up index patterns" link on home page {pull}16128[#16128]
Machine Learning::
* Shows useful error on invalid query in JobList search bar {pull}25153[#25153]
* Adds user privilege check to Jobs List group selector control {pull}25225[#25225]
* Fixes file data viz file size check and formats as bytes {pull}25295[#25295]
* Fixes the layout of the cards in the Data Visualizer on IE {pull}25383[#25383]
* Adds better error reporting for reading and importing data {pull}24269[#24269]
* Displays an ordinal y axis for low cardinality rare charts {pull}24852[#24852]
* Fixes typo in job validation message {pull}25130[#25130]
* Removes deprecated `angularjs` based jobs list and related code {pull}25216[#25216]
Management::
* Adds boilerplate for remote clusters management app {pull}25369[#25369]
* Adds `ignore_failure` to ingest common auto complete in console {pull}24915[#24915]
* Removes support for expression-based scripted fields {pull}14310[#14310]
* Adds WatchErrors to capture invalid watches {pull}23887[#23887]
* Rewords the translation id for error with missing property in Watcher {pull}24753[#24753]
Monitoring::
* Renames Monitoring `FormattedMessage` to `FormattedAlert` {pull}24197[#24197]
* Uses the cluster name from metadata if it exists {pull}24495[#24495]
Operations::
* Removes node fallback from kibana-keystore {pull}15066[#15066]
* Adds debug script to set inspect flags {pull}15967[#15967]
* Uses snake case for scripts/kibana-keystore.js and scripts/kibana-plugin.js {pull}15331[#15331]
* Updates license info in package.json {pull}20353[#20353]
* Fixes error log formatting {pull}24788[#24788]
* Matches chalk dependency version on Kibana with the one used on X-Pack {pull}20621[#20621]
* Fixes non-conforming licenses on devDependencies and adds the ability to whitelist devOnly licenses {pull}23859[#23859]
* Adds jsxa11y into eslint rules {pull}23932[#23932]
* Reverts Bump react-grid-layout to 0.16.0 {pull}14912[#14912]
* Reverts breaking change for Status API {pull}21927[#21927]
* Converts `utils/collection` to TypeScript {pull}23992[#23992]
* Removes usage of update_all_types {pull}16406[#16406]
* Improves the `yarn kbn bootstrap` speed by using yarn workspaces for packages inside `packages/*` and `x-pack` {pull}24095[#24095]
* Runs jenkins:unit task with dev flag in order to run license check {pull}19832[#19832]
* Does not break on startup in debug mode {pull}19219[#19219]
Platform::
* Transforms plugin deprecations before checking for unused settings {pull}21294[#21294]
* Expands list of restricted globals in `eslint-config-kibana` {pull}15798[#15798]
* Makes logs easier to read on Windows with chalk colors {pull}15557[#15557]
Querying &amp; Filtering::
* Fixes wildcard queries against the default field {pull}24778[#24778]
Reporting::
* Returns promise in Reporting jobs API {pull}24769[#24769]
Security::
* Implements the K7 login screen {pull}23512[#23512]
Sharing::
* Fixes issue with debounce function running after component was unmounted {pull}15045[#15045]
Visualizations::
* Defaults the scroll wheel zoom to false on Vega maps {pull}21169[#21169]
* Fixes problem within the input_vis_control plugin that prevents it from updating correctly
if the field is switched, and then switched back to the previous field {pull}25164[#25164]
* Uses `vega-nocanvas` instead of vega lib {pull}16137[#16137]
* Migrates visualization from Angular to React {pull}16425[#16425]
* Fixes maps for reporting (#15272) {pull}15358[#15358]
* Stops creation of nested search source per postflightrequest {pull}20373[#20373]
* Moves inspector code from Vis to embeddable visualize handler {pull}24112[#24112]
* Removes inspector from Vis {pull}24112[#24112]
[[release-notes-8.0.0-alpha1]]
== {kib} 8.0.0-alpha1
coming[8.0.0]

View file

@ -33,6 +33,9 @@ contains the following properties:
`attributes` (required)::
(object) The data to persist
`references` (optional)::
(array) An array of objects with `name`, `id`, and `type` properties that describe the other saved objects this object references. The `name` can be used in the attributes to refer to the other saved object, but never the `id`, which may be updated automatically in the future during migrations or import/export.
`version` (optional)::
(number) Enables specifying a version

View file

@ -33,6 +33,8 @@ Note: You cannot access this endpoint via the Console in Kibana.
`attributes` (required)::
(object) The data to persist
`references` (optional)::
(array) An array of objects with `name`, `id`, and `type` properties that describe the other saved objects this object references. The `name` can be used in the attributes to refer to the other saved object, but never the `id`, which may be updated automatically in the future during migrations or import/export.
==== Examples

View file

@ -29,6 +29,8 @@ Note: You cannot access this endpoint via the Console in Kibana.
(array|string) The fields to return in the response
`sort_field` (optional)::
(string) The field on which the response will be sorted
`has_reference` (optional)::
(object) Filters to objects having a relationship with the type and id combination
[NOTE]
==============================================

View file

@ -26,6 +26,8 @@ Note: You cannot access this endpoint via the Console in Kibana.
`attributes` (required)::
(object) The data to persist
`references` (optional)::
(array) An array of objects with `name`, `id`, and `type` properties that describe the other saved objects this object references. The `name` can be used in the attributes to refer to the other saved object, but never the `id`, which may be updated automatically in the future during migrations or import/export.
==== Examples

View file

@ -3,13 +3,15 @@
[partintro]
--
You can interactively explore your data from the Discover page. You have access to every document in every index that
matches the selected index pattern. You can submit search queries, filter the search results, and view document data.
You can also see the number of documents that match the search query and get field value statistics. If a time field is
configured for the selected index pattern, the distribution of documents over time is displayed in a histogram at the
top of the page.
*Discover* enables you to explore your data with {kib}'s data discovery functions.
You have access to every document in every index that matches the selected index pattern.
You can submit search queries, filter the search results, and view document data.
You can also see the number of documents that match the search query and get field value statistics.
If a time field is configured for the selected index pattern, the distribution of
documents over time is displayed in a histogram at the top of the page.
image::images/Discover-Start-Annotated.png[Discover]
[role="screenshot"]
image::images/Discover-Start.png[Discover]
--
include::discover/set-time-filter.asciidoc[]

View file

@ -1,23 +1,11 @@
[[kuery-query]]
=== Kibana Query Language Enhancements
=== Kibana Query Language
experimental[This functionality is experimental and may be changed or removed completely in a future release.]
In Kibana 6.3, we introduced a number of exciting experimental query language enhancements. These
features are now available by default in 7.0. Out of the box, Kibana's query language now includes scripted field support and a
simplified, easier to use syntax. If you have a Basic license or above, autocomplete functionality will also be enabled.
[NOTE]
============
In 6.0 we introduced an experimental query language called Kuery. We've taken what we learned from that experiment
and applied it to the standard Kibana query language. As a result, Kuery is no longer available as a standalone
option. Saved searches using Kuery will automatically be opted in to using the language enhancements described on
this page. However, some breaking changes have been made to the query syntax, so read on for the full details on
what's new.
============
Starting in 6.3, you can choose to opt-in to a number of exciting experimental query language enhancements under the
options menu in the query bar. Currently, opting in will enable scripted field support and a simplified, easier to
use syntax. If you have a Basic license or above, autocomplete functionality will also be enabled. We're hard at
work building even more features for you to try out. Take these features for a spin and let us know what you think!
==== New Simplified Syntax
==== Language Syntax
If you're familiar with Kibana's old lucene query syntax, you should feel right at home with the new syntax. The basics
stay the same, we've simply refined things to make the query language easier to use. Read about the changes below.

View file

@ -1,11 +1,12 @@
[[search]]
== Searching Your Data
You can search the indices that match the current index pattern by entering
your search criteria in the Query bar. You can use Kibana's standard query language
(based on Lucene https://lucene.apache.org/core/2_9_4/queryparsersyntax.html[query syntax])
or the full JSON-based {ref}/query-dsl.html[Elasticsearch Query DSL]. Autocomplete
and a simplified query syntax are available for the Kibana query language as experimental
features which you can opt-in to under the options menu in the Query Bar.
your search criteria in the Query bar. By default you can use Kibana's standard query language
which features autocomplete and a simple, easy to use syntax. Kibana's legacy query
language (based on Lucene https://lucene.apache.org/core/2_9_4/queryparsersyntax.html[query syntax])
is still available for the time being under the options menu in the Query Bar. When this
legacy query language is selected, the full JSON-based {ref}/query-dsl.html[Elasticsearch Query DSL]
can also be used.
When you submit a search request, the histogram, Documents table, and Fields
list are updated to reflect the search results. The total number of hits
@ -20,15 +21,12 @@ To search your data, enter your search criteria in the Query bar and
press *Enter* or click *Search* image:images/search-button.jpg[] to submit
the request to Elasticsearch.
[NOTE]
===========
You can opt-in to our experimental query features by default by changing `search:queryLanguage`
to `kuery` under Advanced Settings.
===========
include::kuery.asciidoc[]
[[lucene-query]]
=== Lucene Query Syntax
Kibana's query language has historically been based on the Lucene query syntax. The following
Kibana's legacy query language was based on the Lucene query syntax. For the time being this syntax
is still available under the options menu in the Query Bar and in Advanced Settings. The following
are some tips that can help get you started.
* To perform a free text search, simply enter a text string. For example, if
@ -55,7 +53,6 @@ docs.
NOTE: These examples use the Lucene query syntax. When lucene is selected as your
query language you can also submit queries using the {ref}/query-dsl.html[Elasticsearch Query DSL].
include::kuery.asciidoc[]
[[save-open-search]]
=== Saving and Opening Searches

View file

@ -1,45 +1,46 @@
[[set-time-filter]]
== Setting the Time Filter
== Setting the time filter
The time filter restricts the search results to a specific time period. You can
set a time filter if your index contains time-based events and a time-field is
configured for the selected index pattern.
By default the time filter is set to the last 15 minutes. You can use the Time
Picker to change the time filter or select a specific time interval or time
By default the time filter is set to the last 15 minutes. You can use the time
picker to change the time filter, or select a specific time interval or time
range in the histogram at the top of the page.
[role="screenshot"]
To set a time filter with the Time Picker:
[float]
=== Filtering with the time picker
. Click Time Picker image:images/time-picker.jpg[] in the Kibana toolbar.
. To set a quick filter, click one of the shortcut links.
+
image::images/time-filter.jpg[Time filter shortcuts]
. To specify a time filter relative to the current time, click *Relative* and
specify the start time as a number of seconds, minutes, hours, days,
months, or years. You can also specify the end time relative
to the current time. Relative times can be in the past or future.
+
image::images/time-filter-relative.jpg[Relative time filter]
. To specify both the start and end times for the time filter, click
*Absolute* and select a start and end date. You can adjust the time
by editing the *To* and *From* fields.
+
image::images/time-filter-absolute.jpg[Absolute time filter]
. Click the caret in the bottom right corner to close the Time Picker.
You can specify a time filter in one of four ways:
To set a time filter from the histogram, do one of the following:
* *Quick*. Click your desired time window from the options listed.
* *Relative*. Specify a time filter relative to the current time. You can
specify the end time relative to the current time. Relative times can be in the past or future.
* *Absolute*. Specify both the start and end times for the time filter. You can
adjust the time by editing the *To* and *From* fields.
* *Recent*. Click one of the times from your list of recently used time filters.
[role="screenshot"]
image::images/Timepicker-View.png[Time picker menu]
[float]
=== Filtering from the histogram
You can set a time filter from the histogram in one of two ways:
* Click the bar that represents the time interval you want to zoom in on.
* Click and drag to view a specific timespan. You must start the selection with
the cursor over the background of the chart--the cursor changes to a plus sign
when you hover over a valid start point.
To move forward/backward in time, click the arrows to the left or right of the Time Picker:
[role="screenshot"]
image::images/Histogram-Time.png[Time range selector in Histogram]
image::images/time-picker-step.jpg[Move backwards in time]
More options:
* Use the browser Back button to undo your changes.
* To move forward or backward in time, click the arrows to the left or right of the time rage.
* To use a different interval, click the dropdown and select an interval.
You can use the browser Back button to undo your changes.
The displayed time range and interval are shown on the histogram. By default,
the interval is set automatically based on the time range. To use a different
interval, click the link and select an interval.

View file

@ -75,14 +75,14 @@ image::images/tutorial-visualize-pie-3.png[]
To save this chart so you can use it later:
* Click *Save* in the top menu bar and enter `Pie Example`.
Click *Save* in the top menu bar and enter `Pie Example`.
=== Bar chart
You'll use a bar chart to look at the Shakespeare data set and compare
the number of speaking parts in the plays.
* Create a *Vertical Bar* chart and set the search source to `shakes*`.
Create a *Vertical Bar* chart and set the search source to `shakes*`.
Initially, the chart is a single bar that shows the total count
of documents that match the default wildcard query.
@ -114,9 +114,6 @@ Show the plays along the X-axis.
. Give the axis a custom label, `Play Name`.
. Click *Apply changes* image:images/apply-changes-button.png[].
[role="screenshot"]
image::images/0[]
Hovering over a bar shows a tooltip with the number of speaking parts for
that play.
@ -174,7 +171,7 @@ The final visualization is a Markdown widget that renders formatted text.
The Markdown widget uses **markdown** syntax.
> Blockquotes in Markdown use the > character.
. Click *Apply changes* image:images/apply-changes-button.png[].
. Click *Apply changes* image:images/apply-changes-button.png[].
The Markdown renders in the preview pane:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 323 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 385 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 483 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

View file

@ -1,5 +1,5 @@
[[advanced-options]]
== Setting Advanced Options
== Setting advanced options
The *Advanced Settings* page enables you to directly edit settings that control the behavior of the Kibana application.
For example, you can change the format used to display dates, specify the default index pattern, and set the precision
@ -12,18 +12,17 @@ To set advanced options:
. Enter a new value for the option.
. Click the *Save* button.
[float]
[[kibana-settings-reference]]
WARNING: Modifying the following settings can significantly affect Kibana's performance and cause problems that are
difficult to diagnose. Setting a property's value to a blank field will revert to the default behavior, which may not be
compatible with other configuration settings. Deleting a custom setting removes it from Kibana permanently.
.Kibana Settings Reference
.Kibana settings reference
[horizontal]
`query:queryString:options`:: Options for the Lucene query string parser.
`query:allowLeadingWildcards`:: When set, * is allowed as the first character in a query clause. Currently only applies when experimental query features are enabled in the query bar. To disallow leading wildcards in basic lucene queries, use query:queryString:options.
`search:queryLanguage`:: Default is `lucene`. Query language used by the query bar. Choose between the lucene query syntax and kuery, an experimental new language built specifically for Kibana.
`search:queryLanguage`:: Default is `kuery`. Query language used by the query bar. Choose between the lucene query syntax and kuery, a new language built specifically for Kibana.
`sort:options`:: Options for the Elasticsearch {ref}/search-request-sort.html[sort] parameter.
`dateFormat`:: The format to use for displaying pretty-formatted dates.
`dateFormat:tz`:: The timezone that Kibana uses. The default value of `Browser` uses the timezone detected by the browser.

View file

@ -57,6 +57,23 @@ Add one or more configuration blocks to the tag. A tag can have configuration
blocks for different types of {beats}. When the enrolled {beats} run, they will
use the configuration blocks that are valid for their type.
Central management supports configuration settings for:
* {filebeat} modules
* {metricbeat} modules
* {filebeat} inputs
* {filebeat} and {metricbeat} outputs
NOTE: Central management supports the following outputs only: {es}, {ls}, Kafka,
and Redis. Other output types are not supported for {beats} that are enrolled in
central management.
Use the Central Management UI to define and manage settings for supported
configuration blocks. You cannot define those settings in local {beats}
configuration files. For configuration blocks that are not supported by central
management, configure the settings in the local configuration file after
enrolling the Beat in central management.
[float]
=== Manage enrolled {beats}

View file

@ -6,7 +6,9 @@
This section discusses the changes that you need to be aware of when migrating
your application from one version of Kibana to another.
* <<breaking-changes-8.0>>
See also <<release-highlights>> and <<release-notes>>.
--
include::migration/migrate_7_0.asciidoc[]
include::migration/migrate_8_0.asciidoc[]

View file

@ -1,186 +0,0 @@
[[breaking-changes-7.0]]
== Breaking changes in 7.0
++++
<titleabbrev>7.0</titleabbrev>
++++
This section discusses the changes that you need to be aware of when migrating
your application to Kibana 7.0.
See also <<release-highlights>> and <<release-notes>>.
[float]
=== Removed support for users relying on direct index privileges to the Kibana index in Elasticsearch
*Details:* With the introduction of Kibana RBAC in 6.4, users no longer require privileges to the Kibana index in Elasticsearch. Instead, users
should be granted <<kibana-privileges>>. Prior to 7.0, when a user that relies upon direct index privileges logs into Kibana, a deprecation warning is logged. If you are using the `kibana_user` or `kibana_dashboard_only_user` role to grant access to Kibana, or a custom role using <<kibana-privileges>>, no changes are required.
*Impact:* You must change any roles which grant access to Kibana using index privileges to instead use <<kibana-privileges>>. Watcher jobs using the Reporting attachment type must be updated as well.
[float]
=== Removed support for tribe nodes
*Details:* Elasticsearch 7.0 removes the tribe node feature, so Kibana removes it as well.
*Impact:* You must remove any tribe node configurations in Kibana. Consider using <<management-cross-cluster-search>> instead, which does not require kibana.yml configurations in Kibana.
[float]
=== Removed support for running Kibana with a global Node.js installation
*Details:* Previous versions of Kibana would fallback to using a global installation of Node.js if the distribution included with Kibana was not found.
Kibana 7.0 will only use the Node.js distribution included in the package.
*Impact:* There is no expected impact unless Kibana is installed in a non-standard way.
[float]
=== Removed support for using PhantomJS browser for screenshots in Reporting
*Details:* Since the first release of Kibana Reporting, PhantomJS was used as
the headless browser to capture screenshots of Kibana dashboards and
visualizations. In that short time, Chromium has started offering a new
headless browser library and the PhantomJS maintainers abandoned their project.
We started planning for a transition in 6.5.0, when we made Chromium the
default option, but allowed users to continue using Phantom with the
`xpack.reporting.capture.browser.type: phantom` setting. In 7.0, that setting
will still exist for compatibility, but the only valid option will be
`chromium`.
*Impact:* Before upgrading to 7.0, if you have `xpack.reporting.capture.browser.type`
set in kibana.yml, make sure it is set to `chromium`.
[NOTE]
============
Reporting 7.0 uses a version of the Chromium headless browser that RHEL 6,
CentOS 6.x, and other old versions of Linux derived from RHEL 6. This change
effectively removes RHEL 6 OS server support from Kibana Reporting. Users with
RHEL 6 must upgrade to RHEL 7 to use Kibana Reporting starting with version
7.0.0 of the Elastic stack.
============
[float]
=== Advanced setting query:queryString:options no longer applies to filters
*Details:* In previous versions of Kibana the Advanced Setting `query:queryString:options` was applied to both queries
and custom filters using the `query_string` query. This could cause errors if a custom filter used options that
conflicted with the Advanced Setting. In 7.0 `query:queryString:options` will no longer be applied to filters so that
users can have full control over their custom filters.
*Impact:* You must ensure that any saved searches with a `query_string` filter aren't relying implicitly on
`query:queryString:options`.
[float]
=== Advanced setting query:queryString:options no longer applies `default_field: *` by default.
*Details:* Elasticsearch removed the ability to create indices with an _all field in 6.0. As a result, a user could end
up with a mix of indices with and without _all fields if they upgraded from an older version of ES. This could lead to
inconsistent highlighting in Discover. To work around this issue we added `default_field: *` to query:queryString:options
to force consistent querying across indices with and without _all. In 7.0 the _all field will be gone from all indices
so we no longer need this workaround.
*Impact:* Since we'll no longer send the `default_field` parameter in Kibana's query_string query, Elasticsearch
will use the index setting instead. The default for the index setting is also `*`, so most users should not be impacted.
If some of your indices have a non-default `default_field` setting, you may want to update it or re-add the parameter
to Kibana's advanced setting.
[float]
=== Deprecated kibana.yml setting `xpack.monitoring.node_resolver` has been removed
*Details:* This setting has been deprecated since 5.6, when it was explicitly recommended to use `uuid` as its value.
*Impact:* This setting is no longer necessary. If you enable {monitoring} across the Elastic Stack, a monitoring agent runs
on each Elasticsearch node, Logstash node, Kibana instance, and Beat to collect and index metrics. Each node and instance is
considered unique based on its persistent UUID, which is written to the path.data directory when the node or instance starts.
[float]
=== kibana.yml setting `xpack.monitoring.elasticsearch.url` is no longer valid
*Details:* This deprecated setting has been removed and `xpack.monitoring.elasticsearch.hosts` should be used instead.
In prior versions of Kibana, if no port was specified in `xpack.monitoring.elasticsearch.url` a default of 9200 was chosen.
The port in `xpack.monitoring.elasticsearch.hosts` is protocol dependent: https ports will use 443, and http ports will use 80.
*Impact:* Users with `xpack.monitoring.elasticsearch.url` set should use `xpack.monitoring.elasticsearch.hosts` instead and if
`xpack.monitoring.elasticsearch.url` was dependent on an unspecified port set to 9200, `:9200` will have to be appended to the url.
[float]
=== kibana.yml setting `xpack.monitoring.elasticsearch.ssl.cert` is no longer valid
*Details:* This deprecated setting has been removed and `xpack.monitoring.elasticsearch.ssl.certificate` should be used instead.
*Impact:* Users with `xpack.monitoring.elasticsearch.ssl.cert` set should use `xpack.monitoring.elasticsearch.ssl.certificate` instead
[float]
=== kibana.yml setting `xpack.monitoring.elasticsearch.ssl.ca` is no longer valid
*Details:* This deprecated setting has been removed and `xpack.monitoring.elasticsearch.ssl.certificateAuthorities` should be used instead.
*Impact:* Users with `xpack.monitoring.elasticsearch.ssl.ca` set should use `xpack.monitoring.elasticsearch.ssl.certificateAuthorities` instead
[float]
=== kibana.yml setting `xpack.monitoring.elasticsearch.ssl.verify` is no longer valid
*Details:* This deprecated setting has been removed and `xpack.monitoring.elasticsearch.ssl.verificationMode` should be used instead.
*Impact:* Users with `xpack.monitoring.elasticsearch.ssl.verify` set should use `xpack.monitoring.elasticsearch.ssl.verificationMode` instead.
Previously set `xpack.monitoring.elasticsearch.ssl.verify` is equal to `xpack.monitoring.elasticsearch.ssl.verificationMode: full`.
[float]
=== Deprecated API `/shorten` has been removed
*Details:* The `/shorten` API has been deprecated since 6.5, when it was replaced by the `/api/shorten_url` API.
*Impact:* The '/shorten' API has been removed. Use the '/api/shorten_url' API instead.
[float]
=== Deprecated kibana.yml setting logging.useUTC has been replaced with logging.timezone
*Details:* Any timezone can now be specified by canonical id.
*Impact:* The logging.useUTC flag will have to be replaced with a timezone id. If set to true the id is `UTC`.
[float]
=== kibana.yml setting `server.ssl.supportedProtocols` excludes TLSv1 by default
*Details:* TLSv1 support has been removed by default, it's still possible to opt-in to TLSv1 support by explicitly setting
`server.ssl.supportedProtocols`
*Impact:* Users relying upon TLSv1 will be unable to use Kibana unless `server.ssl.supportedProtocols` is explicitly set.
[float]
=== kibana.yml setting `server.ssl.cert` is no longer valid
*Details:* This deprecated setting has been removed and `server.ssl.certificate` should be used instead.
*Impact:* Users with `server.ssl.cert` set should use `server.ssl.certificate` instead
[float]
=== kibana.yml `server.ssl.enabled` must be set to `true` to enable SSL
*Details:* Previously, if `server.ssl.certificate` and `server.ssl.key` were set, SSL would automatically be enabled.
It's now required that the user sets `server.ssl.enabled` to true for this to occur.
*Impact:* Users with both `server.ssl.certificate` and `server.ssl.key` set must now also set `server.ssl.enabled` to enable SSL.
[float]
=== Optimization step deferred until server start
*Details:* Prior versions of Kibana would run the optimization step after each plugin installation. This is now run on server start when necessary.
*Impact:* Users can trigger a standalone optimization after all plugins have been installed with `bin/kibana --optimize` or let the server manage it on startup.
[float]
=== kibana.yml setting `i18n.defaultLocale` is no longer valid
*Details:* This deprecated setting has been removed and `i18n.locale` should be used instead.
*Impact:* Users with `i18n.defaultLocale` set should use `i18n.locale` instead
[float]
=== kibana.yml setting `elasticsearch.url` is no longer valid
*Details:* This deprecated setting has been removed and `elasticsearch.hosts` should be used instead.
In prior versions of Kibana, if no port was specified in `elasticsearch.url` a default of 9200 was chosen. The port in
`elasticsearch.hosts` is protocol dependent: https ports will use 443, and http ports will use 80.
*Impact:* Users with `elasticsearch.url` set should use `elasticsearch.hosts` instead and if `elasticsearch.url` was
dependent on an unspecified port set to 9200, `:9200` will have to be appended to the url.
[float]
=== kibana.yml setting `elasticsearch.ssl.cert` is no longer valid
*Details:* This deprecated setting has been removed and `elasticsearch.ssl.certificate` should be used instead.
*Impact:* Users with `elasticsearch.ssl.cert` set should use `elasticsearch.ssl.certificate` instead
[float]
=== kibana.yml setting `elasticsearch.ssl.ca` is no longer valid
*Details:* This deprecated setting has been removed and `elasticsearch.ssl.certificateAuthorities` should be used instead.
*Impact:* Users with `elasticsearch.ssl.ca` set should use `elasticsearch.ssl.certificateAuthorities` instead
[float]
=== kibana.yml setting `elasticsearch.ssl.verify` is no longer valid
*Details:* This deprecated setting has been removed and `elasticsearch.ssl.verificationMode` should be used instead.
*Impact:* Users with `elasticsearch.ssl.verify` set should use `elasticsearch.ssl.verificationMode` instead.
Previously set `elasticsearch.ssl.verify` is equal to `elasticsearch.ssl.verificationMode: full`.

View file

@ -0,0 +1,12 @@
[[breaking-changes-8.0]]
== Breaking changes in 8.0
++++
<titleabbrev>8.0</titleabbrev>
++++
This section discusses the changes that you need to be aware of when migrating
your application to Kibana 8.0.
coming[8.0.0]
See also <<release-highlights>> and <<release-notes>>.

View file

@ -1,17 +0,0 @@
[[release-notes]]
= Release Notes
[partintro]
--
This section summarizes the changes in each release.
* <<release-notes-7.0.0-alpha2>>
* <<release-notes-7.0.0-alpha1>>
* <<release-notes-6.0.0-alpha2>>
* <<release-notes-6.0.0-alpha1>>
--
include::release-notes/7.0.0-alpha2.asciidoc[]
include::release-notes/7.0.0-alpha1.asciidoc[]
include::release-notes/6.0.0-alpha2.asciidoc[]
include::release-notes/6.0.0-alpha1.asciidoc[]

View file

@ -1,9 +0,0 @@
[[release-highlights-7.0.0]]
== 7.0.0 release highlights
++++
<titleabbrev>7.0.0</titleabbrev>
++++
coming[7.0.0]
See also <<breaking-changes-7.0>> and <<release-notes>>.

View file

@ -0,0 +1,9 @@
[[release-highlights-8.0.0]]
== 8.0.0 release highlights
++++
<titleabbrev>8.0.0</titleabbrev>
++++
coming[8.0.0]
See also <<breaking-changes-8.0,breaking changes>> and <<release-notes>>.

View file

@ -9,8 +9,8 @@
This section summarizes the most important changes in each release. For the
full list, see <<release-notes>> and <<breaking-changes>>.
* <<release-highlights-7.0.0>>
* <<release-highlights-8.0.0>>
--
include::highlights-7.0.0.asciidoc[]
include::highlights-8.0.0.asciidoc[]

View file

@ -31,7 +31,7 @@ image:reporting/images/share-button.png["Reporting Button",link="share-button.pn
.. If you're on Visualize or Dashboard:
... Select *PDF Reports*
... Choose to enable *Optimize for printing* layout mode. For an explanation of the different layout modes, see <<pdf-layout-modes, PDF Layout Modes>>.
... Dashboard only: Choose to enable *Optimize for printing* layout mode. For an explanation of the different layout modes, see <<pdf-layout-modes, PDF Layout Modes>>.
... Click the *Generate PDF* button.

View file

@ -1,7 +1,7 @@
[[pdf-layout-modes]]
== PDF Layout Modes
When creating a PDF report, there are two layout modes *Optimize PDF for printing* and *Preserve existing layout in PDF*
When creating a PDF report of a dashboard, there are two layout modes: *Optimize PDF for printing* and *Preserve existing layout in PDF*
--
[role="screenshot"]
@ -27,3 +27,5 @@ This will create a PDF preserving the existing layout and size of the Visualizat
[role="screenshot"]
image:reporting/images/preserve-layout.png["Preserve existing layout in PDF",link="preserve-layout.png"]
--
When creating a PNG or a PDF report of a visualization, the "Optimize for printing" option will automatically be used.

View file

@ -54,9 +54,6 @@ Specifies the password that {kib} uses for authentication when it retrieves data
from the monitoring cluster. If not set, {kib} uses the value of the
`elasticsearch.password` setting.
`xpack.monitoring.report_stats`::
deprecated[6.3.0, Use `xpack.xpack_main.telemetry.enabled` instead.]
`xpack.xpack_main.telemetry.enabled`::
Set to `true` (default) to send cluster statistics to Elastic. Reporting your
cluster statistics helps us improve your user experience. Your data is never

View file

@ -2,6 +2,7 @@
== Using Kibana in a production environment
* <<configuring-kibana-shield>>
* <<csp-strict-mode>>
* <<enabling-ssl>>
* <<load-balancing>>
@ -36,6 +37,25 @@ which users can load which dashboards.
For information about setting up Kibana users, see
{kibana-ref}/using-kibana-with-security.html[Configuring security in Kibana].
[float]
[[csp-strict-mode]]
=== Require Content Security Policy
Kibana uses a Content Security Policy to help prevent the browser from allowing
unsafe scripting, but older browsers will silently ignore this policy. If your
organization does not need to support Internet Explorer 11 or much older
versions of our other supported browsers, we recommend that you enable Kibana's
`strict` mode for content security policy, which will block access to Kibana
for any browser that does not enforce even a rudimentary set of CSP
protections.
To do this, set `csp.strict` to `true` in your `kibana.yml`:
--------
csp.strict: true
--------
[float]
[[enabling-ssl]]
=== Enabling SSL

View file

@ -19,6 +19,12 @@ you'll need to update your `kibana.yml` file. You can also enable SSL and set a
`cpuacct.cgroup.path.override:`:: Override for cgroup cpuacct path when mounted in manner that is inconsistent with `/proc/self/cgroup`
`csp.rules:`:: A template https://w3c.github.io/webappsec-csp/[content-security-policy] that disables certain unnecessary and potentially insecure capabilities in the browser. All instances of `{nonce}` will be replaced with an automatically generated nonce at load time. We strongly recommend that you keep the default CSP rules that ship with Kibana.
`csp.strict:`:: *Default: `false`* Blocks access to Kibana to any browser that does not enforce even rudimentary CSP rules. In practice, this will disable support for older, less safe browsers like Internet Explorer.
`csp.warnLegacyBrowsers:`:: *Default: `true`* Shows a warning message after loading Kibana to any browser that does not enforce even rudimentary CSP rules, though Kibana is still accessible. This configuration is effectively ignored when `csp.strict` is enabled.
`elasticsearch.customHeaders:`:: *Default: `{}`* Header names and values to send to Elasticsearch. Any custom headers
cannot be overwritten by client-side headers, regardless of the `elasticsearch.requestHeadersWhitelist` configuration.
@ -172,6 +178,7 @@ The minimum value is 100.
`status.allowAnonymous:`:: *Default: false* If authentication is enabled, setting this to `true` allows
unauthenticated users to access the Kibana server status API and status page.
`rollup.enabled:`:: *Default: true* Set this value to false to disable the Rollup user interface.
`license_management.enabled`:: *Default: true* Set this value to false to disable the License Management user interface.
`xpack.rollup.enabled:`:: *Default: true* Set this value to false to disable the Rollup user interface.
`xpack.license_management.enabled`:: *Default: true* Set this value to false to disable the License Management user interface.

View file

@ -2,6 +2,73 @@
[[spaces-securing]]
=== Securing spaces
With security enabled, you can control who has access to specific spaces. You can manage access in **Management > Roles**.
image::spaces/images/securing-spaces.png["Securing spaces"]
With a Gold or Platinum license, you can control which roles have access to
each space. To get started, navigate to **Management > Roles**.
[role="screenshot"]
image::images/spaces_secure_all_privileges.png[]
==== Setting privileges
Access for all spaces in {kib} is governed by a concept called "minimum privilege."
There are three options for minimum privilege:
[cols="2*^<"]
|===
|`all`
|Users have read/write access to all spaces in {kib}. Additionally,
users can create, edit, and delete individual spaces. This extends to spaces
that users create in the future.
|`read`
|Users have read-only access to all spaces in {kib}. This extends to spaces
that users create in the future.
|`none`
|Users do not have the all-spaces access. You must set access on
individual spaces.
|===
Once you set the minimum privilege for all spaces, you can then add read and write
access to individual spaces.
==== Examples
[cols="2*^<"]
|===
s|To provide
s|Do this
|Full access to all spaces
|Set the minimum privilege to `all`. This grants
full access to all spaces. In this case, you can't
customize access to specific spaces.
|Read-only access to all spaces, with full access to specific spaces
|Set the minimum privilege to `read`,
then grant the `all` privilege to individual spaces as needed. You can't revoke
access to an individual space.
|Read-only access to a specific space
|Set the minimum privilege to `none` to prevent all-space access,
then set the `read` privilege for an individual space,
as shown below.
|===
[role="screenshot"]
image::images/spaces_secure_specific_spaces.png[]
[float]
=== Viewing all space privileges
To see which roles have access to each space, click *View summary of spaces privileges*.

View file

@ -11,7 +11,7 @@
"dashboarding"
],
"private": true,
"version": "7.0.0",
"version": "8.0.0",
"branch": "master",
"types": "./kibana.d.ts",
"build": {
@ -50,7 +50,7 @@
"test:coverage": "grunt test:coverage",
"checkLicenses": "grunt licenses --dev",
"build": "node scripts/build --all-platforms",
"start": "node scripts/kibana --dev",
"start": "node --trace-warnings --trace-deprecation scripts/kibana --dev ",
"debug": "node --nolazy --inspect scripts/kibana --dev",
"debug-break": "node --nolazy --inspect-brk scripts/kibana --dev",
"precommit": "node scripts/precommit_hook",
@ -95,7 +95,7 @@
},
"dependencies": {
"@elastic/datemath": "5.0.2",
"@elastic/eui": "6.7.4",
"@elastic/eui": "6.10.1",
"@elastic/filesaver": "1.1.2",
"@elastic/good": "8.1.1-kibana2",
"@elastic/numeral": "2.3.2",
@ -137,8 +137,8 @@
"d3-cloud": "1.2.1",
"del": "^3.0.0",
"dragula": "3.7.0",
"elasticsearch": "^15.2.0",
"elasticsearch-browser": "^15.2.0",
"elasticsearch": "^15.4.1",
"elasticsearch-browser": "^15.4.1",
"encode-uri-query": "1.0.0",
"execa": "^1.0.0",
"expiry-js": "0.1.7",
@ -215,12 +215,11 @@
"rxjs": "^6.2.1",
"script-loader": "0.7.2",
"semver": "^5.5.0",
"socket.io": "^2.1.1",
"stream-stream": "^1.2.6",
"style-loader": "0.23.1",
"tar": "2.2.0",
"terser-webpack-plugin": "^1.1.0",
"thread-loader": "^1.2.0",
"thread-loader": "^2.1.2",
"tinygradient": "0.3.0",
"tinymath": "1.1.1",
"topojson-client": "3.0.0",
@ -242,7 +241,7 @@
"webpack-merge": "4.1.4",
"whatwg-fetch": "^3.0.0",
"wreck": "^14.0.2",
"x-pack": "7.0.0",
"x-pack": "8.0.0",
"yauzl": "2.7.0"
},
"devDependencies": {
@ -250,6 +249,7 @@
"@babel/types": "^7.0.0",
"@elastic/eslint-config-kibana": "0.15.0",
"@elastic/eslint-plugin-kibana-custom": "1.1.0",
"@elastic/makelogs": "^4.4.0",
"@kbn/es": "1.0.0",
"@kbn/eslint-import-resolver-kibana": "2.0.0",
"@kbn/eslint-plugin-license-header": "1.0.0",
@ -344,7 +344,7 @@
"fetch-mock": "7.3.0",
"geckodriver": "1.12.2",
"getopts": "2.0.0",
"grunt": "1.0.1",
"grunt": "1.0.3",
"grunt-cli": "^1.2.0",
"grunt-contrib-watch": "^1.1.0",
"grunt-karma": "2.0.0",
@ -376,6 +376,7 @@
"load-grunt-config": "0.19.2",
"makelogs": "^4.3.0",
"mocha": "3.3.0",
"multistream": "^2.1.1",
"murmurhash3js": "3.0.1",
"mutation-observer": "^1.0.3",
"nock": "10.0.4",
@ -409,7 +410,7 @@
"zlib": "^1.0.5"
},
"engines": {
"node": "10.14.1",
"node": "10.15.1",
"yarn": "^1.10.1"
}
}

View file

@ -1,3 +0,0 @@
{
"presets": ["@kbn/babel-preset/webpack_preset"]
}

View file

@ -0,0 +1,94 @@
# kbn-es-query
This module is responsible for generating Elasticsearch queries for Kibana. See explanations below for each of the subdirectories.
## es_query
This folder contains the code that combines Lucene/KQL queries and filters into an Elasticsearch query.
```javascript
buildEsQuery(indexPattern, queries, filters, config)
```
Generates the Elasticsearch query DSL from combining the queries and filters provided.
```javascript
buildQueryFromFilters(filters, indexPattern)
```
Generates the Elasticsearch query DSL from the given filters.
```javascript
luceneStringToDsl(query)
```
Generates the Elasticsearch query DSL from the given Lucene query.
```javascript
migrateFilter(filter, indexPattern)
```
Migrates a filter from a previous version of Elasticsearch to the current version.
```javascript
decorateQuery(query, queryStringOptions)
```
Decorates an Elasticsearch query_string query with the given options.
## filters
This folder contains the code related to Kibana Filter objects, including their definitions, and helper functions to create them. Filters in Kibana always contain a `meta` property which describes which `index` the filter corresponds to, as well as additional data about the specific filter.
The object that is created by each of the following functions corresponds to a Filter object in the `lib` directory (e.g. `PhraseFilter`, `RangeFilter`, etc.)
```javascript
buildExistsFilter(field, indexPattern)
```
Creates a filter (`ExistsFilter`) where the given field exists.
```javascript
buildPhraseFilter(field, value, indexPattern)
```
Creates an filter (`PhraseFilter`) where the given field matches the given value.
```javascript
buildPhrasesFilter(field, params, indexPattern)
```
Creates a filter (`PhrasesFilter`) where the given field matches one or more of the given values. `params` should be an array of values.
```javascript
buildQueryFilter(query, index)
```
Creates a filter (`CustomFilter`) corresponding to a raw Elasticsearch query DSL object.
```javascript
buildRangeFilter(field, params, indexPattern)
```
Creates a filter (`RangeFilter`) where the value for the given field is in the given range. `params` should contain `lt`, `lte`, `gt`, and/or `gte`.
## kuery
This folder contains the code corresponding to generating Elasticsearch queries using the Kibana query language.
It also contains code corresponding to the original implementation of Kuery (released in 6.0) which should be removed at some point (see legacy_kuery.js, legacy_kuery.peg).
In general, you will only need to worry about the following functions from the `ast` folder:
```javascript
fromExpression(expression)
```
Generates an abstract syntax tree corresponding to the raw Kibana query `expression`.
```javascript
toElasticsearchQuery(node, indexPattern)
```
Takes an abstract syntax tree (generated from the previous method) and generates the Elasticsearch query DSL using the given `indexPattern`. Note that if no `indexPattern` is provided, then an Elasticsearch query DSL will still be generated, ignoring things like the index pattern scripted fields, field types, etc.

View file

@ -0,0 +1,52 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
// We can't use common Kibana presets here because of babel versions incompatibility
module.exports = {
plugins: ['@babel/plugin-proposal-class-properties', '@babel/plugin-proposal-object-rest-spread'],
presets: ['@babel/typescript'],
env: {
public: {
presets: [
[
'@babel/preset-env',
{
targets: {
browsers: ['last 2 versions', '> 5%', 'Safari 7'],
},
modules: false
},
],
],
},
server: {
presets: [
[
'@babel/preset-env',
{
targets: {
node: 'current',
},
},
],
],
},
},
ignore: ['**/__tests__/**/*', '**/*.test.ts', '**/*.test.tsx'],
};

View file

@ -1,20 +1,31 @@
{
"name": "@kbn/es-query",
"main": "target/index.js",
"main": "target/server/index.js",
"browser": "target/public/index.js",
"version": "1.0.0",
"license": "Apache-2.0",
"private": true,
"scripts": {
"build": "babel src --out-dir target",
"kbn:bootstrap": "yarn build --quiet",
"kbn:watch": "yarn build --watch"
"build": "node scripts/build",
"kbn:bootstrap": "node scripts/build --source-maps",
"kbn:watch": "node scripts/build --source-maps --watch"
},
"dependencies": {
"lodash": "npm:@elastic/lodash@3.10.1-kibana1"
},
"devDependencies": {
"@babel/cli": "^7.2.3",
"@babel/core": "^7.2.2",
"@babel/plugin-proposal-class-properties": "^7.3.0",
"@babel/plugin-proposal-object-rest-spread": "^7.3.1",
"@babel/preset-env": "^7.3.1",
"@babel/preset-typescript": "^7.1.0",
"@kbn/babel-preset": "1.0.0",
"babel-cli": "^6.26.0",
"expect.js": "0.3.1"
"@kbn/dev-utils": "1.0.0",
"expect.js": "0.3.1",
"del": "^3.0.0",
"getopts": "^2.2.3",
"supports-color": "^6.1.0",
"typescript": "^3.0.3"
}
}

View file

@ -17,4 +17,4 @@
* under the License.
*/
import './filter_pill';
require('../tasks/build_cli');

View file

@ -75,6 +75,34 @@ describe('build query', function () {
expect(result).to.eql(expectedResult);
});
it('should accept queries and filters as either single objects or arrays', function () {
const queries = { query: 'extension:jpg', language: 'lucene' };
const filters = {
match_all: {},
meta: { type: 'match_all' },
};
const config = {
allowLeadingWildcards: true,
queryStringOptions: {},
};
const expectedResult = {
bool: {
must: [
decorateQuery(luceneStringToDsl('extension:jpg'), config.queryStringOptions),
{ match_all: {} },
],
filter: [],
should: [],
must_not: [],
}
};
const result = buildEsQuery(indexPattern, queries, filters, config);
expect(result).to.eql(expectedResult);
});
});
});

View file

@ -56,7 +56,7 @@ describe('build query', function () {
const oldQuery = { query: 'is(foo, bar)', language: 'kuery' };
expect(buildQueryFromKuery).withArgs(indexPattern, [oldQuery], true).to.throwError(
/It looks like you're using an outdated Kuery syntax./
/OutdatedKuerySyntaxError/
);
});

View file

@ -24,8 +24,8 @@ import { buildQueryFromLucene } from './from_lucene';
/**
* @param indexPattern
* @param queries - an array of query objects. Each query has a language property and a query property.
* @param filters - an array of filter objects
* @param queries - a query object or array of query objects. Each query has a language property and a query property.
* @param filters - a filter object or array of filter objects
* @param config - an objects with query:allowLeadingWildcards and query:queryString:options UI
* settings in form of { allowLeadingWildcards, queryStringOptions }
*/
@ -33,15 +33,18 @@ export function buildEsQuery(
indexPattern,
queries = [],
filters = [],
{
allowLeadingWildcards = false,
queryStringOptions = {},
config = {
allowLeadingWildcards: false,
queryStringOptions: {},
}) {
queries = Array.isArray(queries) ? queries : [queries];
filters = Array.isArray(filters) ? filters : [filters];
const validQueries = queries.filter((query) => has(query, 'query'));
const queriesByLanguage = groupBy(validQueries, 'language');
const kueryQuery = buildQueryFromKuery(indexPattern, queriesByLanguage.kuery, allowLeadingWildcards);
const luceneQuery = buildQueryFromLucene(queriesByLanguage.lucene, queryStringOptions);
const kueryQuery = buildQueryFromKuery(indexPattern, queriesByLanguage.kuery, config.allowLeadingWildcards);
const luceneQuery = buildQueryFromLucene(queriesByLanguage.lucene, config.queryStringOptions);
const filterQuery = buildQueryFromFilters(filters, indexPattern);
return {

View file

@ -17,6 +17,7 @@
* under the License.
*/
// Creates a filter where the given field exists
export function buildExistsFilter(field, indexPattern) {
return {
meta: {

View file

@ -17,27 +17,31 @@
* under the License.
*/
import { get } from 'lodash';
import { Field, IndexPattern } from 'ui/index_patterns';
import { CustomFilter, ExistsFilter, PhraseFilter, PhrasesFilter, RangeFilter } from './lib';
import { RangeFilterParams } from './lib/range_filter';
import { collectIndexPatterns } from './collect_index_patterns';
import { collectSearchSources } from './collect_search_sources';
export * from './lib';
export function buildExistsFilter(field: Field, indexPattern: IndexPattern): ExistsFilter;
export async function collectPanels(savedObjectsClient, dashboard) {
let panels;
try {
panels = JSON.parse(get(dashboard, 'attributes.panelsJSON', '[]'));
} catch(err) {
panels = [];
}
export function buildPhraseFilter(
field: Field,
value: string,
indexPattern: IndexPattern
): PhraseFilter;
if (panels.length === 0) return [].concat([dashboard]);
export function buildPhrasesFilter(
field: Field,
values: string[],
indexPattern: IndexPattern
): PhrasesFilter;
const { saved_objects: savedObjects } = await savedObjectsClient.bulkGet(panels);
const [ indexPatterns, searchSources ] = await Promise.all([
collectIndexPatterns(savedObjectsClient, savedObjects),
collectSearchSources(savedObjectsClient, savedObjects)
]);
export function buildQueryFilter(query: any, index: string): CustomFilter;
return savedObjects.concat(indexPatterns).concat(searchSources).concat([dashboard]);
}
export function buildRangeFilter(
field: Field,
params: RangeFilterParams,
indexPattern: IndexPattern,
formattedValue?: string
): RangeFilter;

View file

@ -22,3 +22,4 @@ export * from './phrase';
export * from './phrases';
export * from './query';
export * from './range';
export * from './lib';

View file

@ -0,0 +1,24 @@
/*
* 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 { Filter } from './meta_filter';
export type CustomFilter = Filter & {
query: any;
};

View file

@ -17,13 +17,10 @@
* under the License.
*/
export const timeUnits = {
s: 'second',
m: 'minute',
h: 'hour',
d: 'day',
w: 'week',
M: 'month',
y: 'year'
};
import { Filter, FilterMeta } from './meta_filter';
export type ExistsFilterMeta = FilterMeta;
export type ExistsFilter = Filter & {
meta: ExistsFilterMeta;
};

View file

@ -0,0 +1,31 @@
/*
* 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 { Filter, FilterMeta, LatLon } from './meta_filter';
export type GeoBoundingBoxFilterMeta = FilterMeta & {
params: {
bottom_right: LatLon;
top_left: LatLon;
};
};
export type GeoBoundingBoxFilter = Filter & {
meta: GeoBoundingBoxFilterMeta;
};

View file

@ -0,0 +1,30 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { Filter, FilterMeta, LatLon } from './meta_filter';
export type GeoPolygonFilterMeta = FilterMeta & {
params: {
points: LatLon[];
};
};
export type GeoPolygonFilter = Filter & {
meta: GeoPolygonFilterMeta;
};

View file

@ -0,0 +1,50 @@
/*
* 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.
*/
// The interface the other filters extend
export * from './meta_filter';
// The actual filter types
import { CustomFilter } from './custom_filter';
import { ExistsFilter } from './exists_filter';
import { GeoBoundingBoxFilter } from './geo_bounding_box_filter';
import { GeoPolygonFilter } from './geo_polygon_filter';
import { PhraseFilter } from './phrase_filter';
import { PhrasesFilter } from './phrases_filter';
import { QueryStringFilter } from './query_string_filter';
import { RangeFilter } from './range_filter';
export {
CustomFilter,
ExistsFilter,
GeoBoundingBoxFilter,
GeoPolygonFilter,
PhraseFilter,
PhrasesFilter,
QueryStringFilter,
RangeFilter,
};
// Any filter associated with a field (used in the filter bar/editor)
export type FieldFilter =
| ExistsFilter
| GeoBoundingBoxFilter
| GeoPolygonFilter
| PhraseFilter
| PhrasesFilter
| RangeFilter;

View file

@ -0,0 +1,100 @@
/*
* 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 enum FilterStateStore {
APP_STATE = 'appState',
GLOBAL_STATE = 'globalState',
}
export interface FilterState {
store: FilterStateStore;
}
export interface FilterMeta {
// index and type are optional only because when you create a new filter, there are no defaults
index?: string;
type?: string;
disabled: boolean;
negate: boolean;
alias: string | null;
key?: string;
value?: string;
}
export interface Filter {
$state: FilterState;
meta: FilterMeta;
query?: any;
}
export interface LatLon {
lat: number;
lon: number;
}
export function buildEmptyFilter(isPinned: boolean, index?: string): Filter {
const meta: FilterMeta = {
disabled: false,
negate: false,
alias: null,
index,
};
const $state: FilterState = {
store: isPinned ? FilterStateStore.GLOBAL_STATE : FilterStateStore.APP_STATE,
};
return { meta, $state };
}
export function isFilterPinned(filter: Filter) {
return filter.$state.store === FilterStateStore.GLOBAL_STATE;
}
export function toggleFilterDisabled(filter: Filter) {
const disabled = !filter.meta.disabled;
const meta = { ...filter.meta, disabled };
return { ...filter, meta };
}
export function toggleFilterNegated(filter: Filter) {
const negate = !filter.meta.negate;
const meta = { ...filter.meta, negate };
return { ...filter, meta };
}
export function toggleFilterPinned(filter: Filter) {
const store = isFilterPinned(filter) ? FilterStateStore.APP_STATE : FilterStateStore.GLOBAL_STATE;
const $state = { ...filter.$state, store };
return { ...filter, $state };
}
export function enableFilter(filter: Filter) {
return !filter.meta.disabled ? filter : toggleFilterDisabled(filter);
}
export function disableFilter(filter: Filter) {
return filter.meta.disabled ? filter : toggleFilterDisabled(filter);
}
export function pinFilter(filter: Filter) {
return isFilterPinned(filter) ? filter : toggleFilterPinned(filter);
}
export function unpinFilter(filter: Filter) {
return !isFilterPinned(filter) ? filter : toggleFilterPinned(filter);
}

View file

@ -0,0 +1,30 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { Filter, FilterMeta } from './meta_filter';
export type PhraseFilterMeta = FilterMeta & {
params: {
query: string; // The unformatted value
};
};
export type PhraseFilter = Filter & {
meta: PhraseFilterMeta;
};

View file

@ -0,0 +1,28 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { Filter, FilterMeta } from './meta_filter';
export type PhrasesFilterMeta = FilterMeta & {
params: string[]; // The unformatted values
};
export type PhrasesFilter = Filter & {
meta: PhrasesFilterMeta;
};

View file

@ -17,9 +17,10 @@
* under the License.
*/
export const TIME_MODES = {
ABSOLUTE: 'absolute',
QUICK: 'quick',
RECENT: 'recent',
RELATIVE: 'relative',
import { Filter, FilterMeta } from './meta_filter';
export type QueryStringFilterMeta = FilterMeta;
export type QueryStringFilter = Filter & {
meta: QueryStringFilterMeta;
};

View file

@ -17,23 +17,19 @@
* under the License.
*/
export const rangeFilter = {
'meta': {
'index': 'logstash-*',
'negate': false,
'disabled': false,
'alias': null,
'type': 'range',
'key': 'bytes',
'value': '0 to 10'
},
'range': {
'bytes': {
'gte': 0,
'lt': 10
}
},
'$state': {
'store': 'appState'
}
import { Filter, FilterMeta } from './meta_filter';
export interface RangeFilterParams {
gt?: number | string;
gte?: number | string;
lte?: number | string;
lt?: number | string;
}
export type RangeFilterMeta = FilterMeta & {
params: RangeFilterParams;
};
export type RangeFilter = Filter & {
meta: RangeFilterMeta;
};

View file

@ -17,6 +17,7 @@
* under the License.
*/
// Creates an filter where the given field matches the given value
export function buildPhraseFilter(field, value, indexPattern) {
const filter = { meta: { index: indexPattern.id } };
const convertedValue = getConvertedValueForField(field, value);

View file

@ -19,6 +19,8 @@
import { getPhraseScript } from './phrase';
// Creates a filter where the given field matches one or more of the given values
// params should be an array of values
export function buildPhrasesFilter(field, params, indexPattern) {
const index = indexPattern.id;
const type = 'phrases';

View file

@ -17,6 +17,7 @@
* under the License.
*/
// Creates a filter corresponding to a raw Elasticsearch query DSL object
export function buildQueryFilter(query, index) {
return {
query: query,

View file

@ -36,6 +36,8 @@ function formatValue(field, params) {
return _.map(params, (val, key) => operators[key] + format(field, val)).join(' ');
}
// Creates a filter where the value for the given field is in the given range
// params should be an object containing `lt`, `lte`, `gt`, and/or `gte`
export function buildRangeFilter(field, params, indexPattern, formattedValue) {
const filter = { meta: { index: indexPattern.id } };
if (formattedValue) filter.meta.formattedValue = formattedValue;

View file

@ -18,3 +18,4 @@
*/
export * from './kuery';
export * from './filters';

View file

@ -0,0 +1,103 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
const { resolve } = require('path');
const getopts = require('getopts');
const del = require('del');
const supportsColor = require('supports-color');
const { ToolingLog, withProcRunner, pickLevelFromFlags } = require('@kbn/dev-utils');
const ROOT_DIR = resolve(__dirname, '..');
const BUILD_DIR = resolve(ROOT_DIR, 'target');
const padRight = (width, str) =>
str.length >= width ? str : `${str}${' '.repeat(width - str.length)}`;
const unknownFlags = [];
const flags = getopts(process.argv, {
boolean: ['watch', 'help', 'source-maps'],
unknown(name) {
unknownFlags.push(name);
},
});
const log = new ToolingLog({
level: pickLevelFromFlags(flags),
writeTo: process.stdout,
});
if (unknownFlags.length) {
log.error(`Unknown flag(s): ${unknownFlags.join(', ')}`);
flags.help = true;
process.exitCode = 1;
}
if (flags.help) {
log.info(`
Simple build tool for @kbn/es-query package
--watch Run in watch mode
--source-maps Include sourcemaps
--help Show this message
`);
process.exit();
}
withProcRunner(log, async proc => {
log.info('Deleting old output');
await del(BUILD_DIR);
const cwd = ROOT_DIR;
const env = { ...process.env };
if (supportsColor.stdout) {
env.FORCE_COLOR = 'true';
}
log.info(`Starting babel and typescript${flags.watch ? ' in watch mode' : ''}`);
await Promise.all([
...['public', 'server'].map(subTask =>
proc.run(padRight(12, `babel:${subTask}`), {
cmd: 'babel',
args: [
'src',
'--config-file',
require.resolve('../babel.config.js'),
'--out-dir',
resolve(BUILD_DIR, subTask),
'--extensions',
'.js,.ts,.tsx',
...(flags.watch ? ['--watch'] : ['--quiet']),
...(flags['source-maps'] ? ['--source-map', 'inline'] : []),
],
wait: true,
cwd,
env: {
...env,
BABEL_ENV: subTask,
},
})
),
]);
log.success('Complete');
}).catch(error => {
log.error(error);
process.exit(1);
});

View file

@ -0,0 +1,11 @@
{
"extends": "../../tsconfig.browser.json",
"compilerOptions": {
"rootDir": "./src",
"outDir": "./target/public"
},
"include": [
"index.d.ts",
"src/**/*.ts"
]
}

View file

@ -1,7 +1,11 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"rootDir": "./src",
"outDir": "./target/server"
},
"include": [
"index.d.ts",
"src/**/*.d.ts"
"src/**/*.ts"
]
}

View file

@ -145,10 +145,24 @@ function downloadFile(url, dest, log) {
}
function getFilename(license, version) {
const extension = os.platform().startsWith('win') ? 'zip' : 'tar.gz';
const basename = `elasticsearch${license === 'oss' ? '-oss-' : '-'}${version}`;
const platform = os.platform();
let suffix = null;
switch (platform) {
case 'darwin':
suffix = 'darwin-x86_64.tar.gz';
break;
case 'linux':
suffix = 'linux-x86_64.tar.gz';
break;
case 'win32':
suffix = 'windows-x86_64.zip';
break;
default:
throw new Error(`Unsupported platform ${platform}`);
}
return `${basename}-SNAPSHOT.${extension}`;
const basename = `elasticsearch${license === 'oss' ? '-oss-' : '-'}${version}`;
return `${basename}-SNAPSHOT-${suffix}`;
}
function getUrl(fileName) {

View file

@ -20,6 +20,7 @@
const execa = require('execa');
const path = require('path');
const fs = require('fs');
const os = require('os');
const readline = require('readline');
const chalk = require('chalk');
const crypto = require('crypto');
@ -27,7 +28,7 @@ const simpleGit = require('simple-git/promise');
const { installArchive } = require('./archive');
const { createCliError } = require('../errors');
const { findMostRecentlyChanged, log: defaultLog, cache } = require('../utils');
const { GRADLE_BIN, ES_ARCHIVE_PATTERN, ES_OSS_ARCHIVE_PATTERN, BASE_PATH } = require('../paths');
const { GRADLE_BIN, BASE_PATH } = require('../paths');
const onceEvent = (emitter, event) => new Promise(resolve => emitter.once(event, resolve));
@ -89,6 +90,7 @@ async function sourceInfo(cwd, license, log = defaultLog) {
const git = simpleGit(cwd);
const { task, ext } = archiveForPlatform(os.platform(), license);
const status = await git.status();
const branch = status.current;
const sha = (await git.revparse(['HEAD'])).trim();
@ -110,8 +112,8 @@ async function sourceInfo(cwd, license, log = defaultLog) {
.digest('hex')
.substr(0, 8);
const basename = `${branch}${license === 'oss' ? '-oss-' : '-'}${cwdHash}`;
const filename = `${basename}.tar.gz`;
const basename = `${branch}-${task}-${cwdHash}`;
const filename = `${basename}.${ext}`;
return {
etag: etag.digest('hex'),
@ -129,10 +131,18 @@ async function sourceInfo(cwd, license, log = defaultLog) {
* @property {String} options.sourcePath
* @property {ToolingLog} options.log
* @returns {Object} containing archive and optional plugins
*
* Gradle tasks:
* :distribution:archives:darwin-tar:assemble
* :distribution:archives:linux-tar:assemble
* :distribution:archives:windows-zip:assemble
* :distribution:archives:oss-darwin-tar:assemble
* :distribution:archives:oss-linux-tar:assemble
* :distribution:archives:oss-windows-zip:assemble
*/
async function createSnapshot({ license, sourcePath, log = defaultLog }) {
const tarTask = license === 'oss' ? 'oss-tar' : 'tar';
const buildArgs = [`:distribution:archives:${tarTask}:assemble`];
const { task, ext } = archiveForPlatform(os.platform(), license);
const buildArgs = [`:distribution:archives:${task}:assemble`];
log.info('%s %s', GRADLE_BIN, buildArgs.join(' '));
@ -157,12 +167,27 @@ async function createSnapshot({ license, sourcePath, log = defaultLog }) {
throw createCliError('unable to build ES');
}
const archivePattern = license === 'oss' ? ES_OSS_ARCHIVE_PATTERN : ES_ARCHIVE_PATTERN;
const esTarballPath = findMostRecentlyChanged(path.resolve(sourcePath, archivePattern));
const archivePattern = `distribution/archives/${task}/build/distributions/elasticsearch-*.${ext}`;
const esArchivePath = findMostRecentlyChanged(path.resolve(sourcePath, archivePattern));
if (!esTarballPath) {
if (!esArchivePath) {
throw createCliError('could not locate ES distribution');
}
return esTarballPath;
return esArchivePath;
}
function archiveForPlatform(platform, license) {
const taskPrefix = license === 'oss' ? 'oss-' : '';
switch (platform) {
case 'darwin':
return { format: 'tar', ext: 'tar.gz', task: `${taskPrefix}darwin-tar`, platform: 'darwin' };
case 'win32':
return { format: 'zip', ext: 'zip', task: `${taskPrefix}windows-zip`, platform: 'windows' };
case 'linux':
return { format: 'tar', ext: 'tar.gz', task: `${taskPrefix}linux-tar`, platform: 'linux' };
default:
throw new Error(`unknown platform: ${platform}`);
}
}

View file

@ -33,8 +33,3 @@ exports.ES_BIN = useBat('bin/elasticsearch');
exports.ES_CONFIG = 'config/elasticsearch.yml';
exports.ES_KEYSTORE_BIN = useBat('./bin/elasticsearch-keystore');
exports.ES_ARCHIVE_PATTERN =
'distribution/archives/tar/build/distributions/elasticsearch-*-SNAPSHOT.tar.gz';
exports.ES_OSS_ARCHIVE_PATTERN =
'distribution/archives/oss-tar/build/distributions/elasticsearch-*-SNAPSHOT.tar.gz';

View file

@ -163,7 +163,7 @@ import { i18n } from '@kbn/i18n';
export const HELLO_WORLD = i18n.translate('hello.wonderful.world', {
defaultMessage: 'Greetings, planet Earth!',
}),
});
```
One more example with a parameter:
@ -254,18 +254,7 @@ Optionally we can pass `description` prop into `FormattedMessage` component.
This prop is optional context comment that will be extracted by i18n tools
and added as a comment next to translation message at `defaultMessages.json`
In case when ReactJS component is rendered with the help of `reactDirective` AngularJS service, it's necessary to use React HOC `injectI18nProvider` to pass `intl` object to `FormattedMessage` component via context.
```js
import { injectI18nProvider } from '@kbn/i18n/react';
import { Header } from './components/header';
module.directive('headerGlobalNav', (reactDirective) => {
return reactDirective(injectI18nProvider(Header));
});
```
**NOTE:** To minimize the chance of having multiple `I18nProvider` components in the React tree, try to use `injectI18nProvider` or `I18nProvider` only to wrap the topmost component that you render, e.g. the one that's passed to `reactDirective` or `ReactDOM.render`.
**NOTE:** To minimize the chance of having multiple `I18nProvider` components in the React tree, try to use `I18nProvider` only to wrap the topmost component that you render, e.g. the one that's passed to `reactDirective` or `ReactDOM.render`.
### FormattedRelative

View file

@ -12,19 +12,19 @@
"kbn:watch": "node scripts/build --watch --source-maps"
},
"devDependencies": {
"@babel/cli": "^7.1.0",
"@babel/core": "^7.1.0",
"@babel/plugin-proposal-class-properties": "^7.1.0",
"@babel/plugin-proposal-object-rest-spread": "^7.0.0",
"@babel/preset-env": "^7.1.0",
"@babel/cli": "^7.2.3",
"@babel/core": "^7.2.2",
"@babel/plugin-proposal-class-properties": "^7.3.0",
"@babel/plugin-proposal-object-rest-spread": "^7.3.1",
"@babel/preset-env": "^7.3.1",
"@babel/preset-react": "^7.0.0",
"@babel/preset-typescript": "^7.1.0",
"@kbn/dev-utils": "1.0.0",
"@types/intl-relativeformat": "^2.1.0",
"@types/react-intl": "^2.3.11",
"@types/react-intl": "^2.3.15",
"del": "^3.0.0",
"getopts": "^2.2.3",
"supports-color": "^5.5.0",
"supports-color": "^6.1.0",
"typescript": "^3.0.3"
},
"dependencies": {
@ -32,7 +32,7 @@
"intl-messageformat": "^2.2.0",
"intl-relativeformat": "^2.1.0",
"prop-types": "^15.6.2",
"react": "^16.3.0",
"react-intl": "^2.7.0"
"react": "^16.6.0",
"react-intl": "^2.8.0"
}
}

View file

@ -1,110 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`injectI18nProvider provides with context 1`] = `
Object {
"defaultFormats": Object {},
"defaultLocale": "en",
"formatDate": [Function],
"formatHTMLMessage": [Function],
"formatMessage": [Function],
"formatNumber": [Function],
"formatPlural": [Function],
"formatRelative": [Function],
"formatTime": [Function],
"formats": Object {
"date": Object {
"full": Object {
"day": "numeric",
"month": "long",
"weekday": "long",
"year": "numeric",
},
"long": Object {
"day": "numeric",
"month": "long",
"year": "numeric",
},
"medium": Object {
"day": "numeric",
"month": "short",
"year": "numeric",
},
"short": Object {
"day": "numeric",
"month": "numeric",
"year": "2-digit",
},
},
"number": Object {
"currency": Object {
"style": "currency",
},
"percent": Object {
"style": "percent",
},
},
"relative": Object {
"days": Object {
"units": "day",
},
"hours": Object {
"units": "hour",
},
"minutes": Object {
"units": "minute",
},
"months": Object {
"units": "month",
},
"seconds": Object {
"units": "second",
},
"years": Object {
"units": "year",
},
},
"time": Object {
"full": Object {
"hour": "numeric",
"minute": "numeric",
"second": "numeric",
"timeZoneName": "short",
},
"long": Object {
"hour": "numeric",
"minute": "numeric",
"second": "numeric",
"timeZoneName": "short",
},
"medium": Object {
"hour": "numeric",
"minute": "numeric",
"second": "numeric",
},
"short": Object {
"hour": "numeric",
"minute": "numeric",
},
},
},
"formatters": Object {
"getDateTimeFormat": [Function],
"getMessageFormat": [Function],
"getNumberFormat": [Function],
"getPluralFormat": [Function],
"getRelativeFormat": [Function],
},
"locale": "en",
"messages": Object {},
"now": [Function],
"onError": [Function],
"textComponent": Symbol(react.fragment),
"timeZone": null,
}
`;
exports[`injectI18nProvider renders children 1`] = `
<I18nProvider>
<ChildrenMock />
</I18nProvider>
`;

View file

@ -30,5 +30,4 @@ export {
} from 'react-intl';
export { I18nProvider } from './provider';
export { injectI18nProvider } from './inject_i18n_provider';
export { injectI18n } from './inject';

View file

@ -1,47 +0,0 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { mount, shallow } from 'enzyme';
import * as React from 'react';
import { intlShape } from 'react-intl';
import { injectI18n } from './inject';
import { injectI18nProvider } from './inject_i18n_provider';
describe('injectI18nProvider', () => {
test('renders children', () => {
const ChildrenMock = () => null;
const Injected = injectI18nProvider(ChildrenMock);
expect(shallow(<Injected />)).toMatchSnapshot();
});
test('provides with context', () => {
const ChildrenMock = () => <div />;
const WithIntl = injectI18n(ChildrenMock);
const Injected = injectI18nProvider(WithIntl);
const wrapper = mount(<Injected />, {
childContextTypes: {
intl: intlShape,
},
});
expect(wrapper.find(ChildrenMock).prop('intl')).toMatchSnapshot();
});
});

View file

@ -12,8 +12,6 @@
"@kbn/i18n": "1.0.0",
"lodash": "npm:@elastic/lodash@3.10.1-kibana1",
"lodash.clone": "^4.5.0",
"scriptjs": "^2.5.8",
"socket.io-client": "^2.1.1",
"uuid": "3.0.1"
},
"devDependencies": {
@ -24,8 +22,8 @@
"babel-loader": "7.1.5",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-polyfill": "6.20.0",
"css-loader": "1.0.0",
"copy-webpack-plugin": "^4.6.0",
"css-loader": "1.0.0",
"del": "^3.0.0",
"getopts": "^2.2.3",
"pegjs": "0.9.0",
@ -36,4 +34,4 @@
"webpack": "4.23.1",
"webpack-cli": "^3.1.2"
}
}
}

View file

@ -20,7 +20,7 @@
export { FunctionsRegistry } from './lib/functions_registry';
export { TypesRegistry } from './lib/types_registry';
export { createError } from './interpreter/create_error';
export { interpretProvider } from './interpreter/interpret';
export { interpreterProvider } from './interpreter/interpret';
export { serializeProvider } from './lib/serialize';
export { fromExpression, toExpression, safeElementFromExpression } from './lib/ast';
export { Fn } from './lib/fn';
@ -29,3 +29,4 @@ export { castProvider } from './interpreter/cast';
export { parse } from './lib/grammar';
export { getByAlias } from './lib/get_by_alias';
export { Registry } from './lib/registry';
export { addRegistries, register, registryFactory } from './registries';

View file

@ -25,8 +25,8 @@ import { getByAlias } from '../lib/get_by_alias';
import { castProvider } from './cast';
import { createError } from './create_error';
export function interpretProvider(config) {
const { functions, onFunctionNotFound, types } = config;
export function interpreterProvider(config) {
const { functions, types } = config;
const handlers = { ...config.handlers, types };
const cast = castProvider(types);
@ -54,15 +54,8 @@ export function interpretProvider(config) {
const { function: fnName, arguments: fnArgs } = link;
const fnDef = getByAlias(functions, fnName);
// if the function is not found, pass the expression chain to the not found handler
// in this case, it will try to execute the function in another context
if (!fnDef) {
chain.unshift(link);
try {
return await onFunctionNotFound({ type: 'expression', chain: chain }, context);
} catch (e) {
return createError(e);
}
return createError({ message: `Function ${fnName} could not be found.` });
}
try {

View file

@ -1,81 +0,0 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import uuid from 'uuid/v4';
import { getByAlias } from '../lib/get_by_alias';
import { serializeProvider } from '../lib/serialize';
import { interpretProvider } from './interpret';
/*
Returns an interpet function that can shuttle partial ASTs and context between instances of itself over a socket
This is the interpreter that gets called during interactive sessions in the browser and communicates with the
same instance on the backend
types: a registry of types
functions: registry of known functions
referableFunctions: An array, or a promise for an array, with a list of functions that are available to be defered to
socket: the socket to communicate over
*/
export function socketInterpreterProvider({
types,
functions,
handlers,
referableFunctions,
socket,
}) {
// Return the interpet() function
return interpretProvider({
types,
functions,
handlers,
onFunctionNotFound: (ast, context) => {
// Get the name of the function that wasn't found
const functionName = ast.chain[0].function;
// Get the list of functions that are known elsewhere
return Promise.resolve(referableFunctions).then(referableFunctionMap => {
// Check if the not-found function is in the list of alternatives, if not, throw
if (!getByAlias(referableFunctionMap, functionName)) {
throw new Error(`Function not found: ${functionName}`);
}
// set a unique message ID so the code knows what response to process
const id = uuid();
return new Promise(resolve => {
const { serialize, deserialize } = serializeProvider(types);
// This will receive {type: [msgSuccess || msgError] value: foo}
// However it doesn't currently do anything with it. Which means `value`, regardless
// of failure or success, needs to be something the interpreters would logically return
// er, a primative or a {type: foo} object
const listener = resp => resolve(deserialize(resp.value));
socket.once(`resp:${id}`, listener);
// Go run the remaining AST and context somewhere else, meaning either the browser or the server, depending on
// where this file was loaded
socket.emit('run', { ast, context: serialize(context), id });
});
});
},
});
}

View file

@ -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.
*/
/**
* Add a new set of registries to an existing set of registries.
*
* @param {*} registries - The existing set of registries
* @param {*} newRegistries - The new set of registries
*/
export function addRegistries(registries, newRegistries) {
Object.keys(newRegistries).forEach(registryName => {
if (registries[registryName]) {
throw new Error(`There is already a registry named "${registryName}".`);
}
registries[registryName] = newRegistries[registryName];
});
return registries;
}
/**
* Register a set of interpreter specs (functions, types, renderers, etc)
*
* @param {*} registries - The set of registries
* @param {*} specs - The specs to be regsitered (e.g. { types: [], browserFunctions: [] })
*/
export function register(registries, specs) {
Object.keys(specs).forEach(registryName => {
if (!registries[registryName]) {
throw new Error(`There is no registry named "${registryName}".`);
}
if (!registries[registryName].register) {
throw new Error(`Registry "${registryName}" must have a register function.`);
}
specs[registryName].forEach(f => registries[registryName].register(f));
});
return registries;
}
/**
* A convenience function for exposing registries and register in a plugin-friendly way
* as a global in the browser, and as server.plugins.interpreter.register | registries
* on the server.
*
* @param {*} registries - The registries to wrap.
*/
export function registryFactory(registries) {
return {
// This is a getter function. We can't make it a property or a proper
// getter, because Kibana server will improperly clone it.
registries() {
return registries;
},
register(specs) {
return register(registries, specs);
},
};
}

View file

@ -0,0 +1,111 @@
/*
* 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 { FUNCTIONS_URL } from './consts';
/**
* Create a function which executes an Expression function on the
* server as part of a larger batch of executions.
*/
export function batchedFetch({ kfetch, serialize, ms = 10 }) {
// Uniquely identifies each function call in a batch operation
// so that the appropriate promise can be resolved / rejected later.
let id = 0;
// A map like { id: { future, request } }, which is used to
// track all of the function calls in a batch operation.
let batch = {};
let timeout;
const nextId = () => ++id;
const reset = () => {
id = 0;
batch = {};
timeout = undefined;
};
const runBatch = () => {
processBatch(kfetch, batch);
reset();
};
return ({ functionName, context, args }) => {
if (!timeout) {
timeout = setTimeout(runBatch, ms);
}
const id = nextId();
const future = createFuture();
batch[id] = {
future,
request: { id, functionName, args, context: serialize(context) },
};
return future.promise;
};
}
/**
* An externally resolvable / rejectable promise, used to make sure
* individual batch responses go to the correct caller.
*/
function createFuture() {
let resolve;
let reject;
return {
resolve(val) { return resolve(val); },
reject(val) { return reject(val); },
promise: new Promise((res, rej) => {
resolve = res;
reject = rej;
}),
};
}
/**
* Runs the specified batch of functions on the server, then resolves
* the related promises.
*/
async function processBatch(kfetch, batch) {
try {
const { results } = await kfetch({
pathname: FUNCTIONS_URL,
method: 'POST',
body: JSON.stringify({
functions: Object.values(batch).map(({ request }) => request),
}),
});
results.forEach(({ id, result }) => {
const { future } = batch[id];
if (result.statusCode && result.err) {
future.reject(result);
} else {
future.resolve(result);
}
});
} catch (err) {
Object.values(batch).forEach(({ future }) => {
future.reject(err);
});
}
}

View file

@ -1,49 +0,0 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { i18n } from '@kbn/i18n';
import $script from 'scriptjs';
export const loadBrowserRegistries = (registries, basePath) => {
const remainingTypes = Object.keys(registries);
const populatedTypes = {};
return new Promise(resolve => {
function loadType() {
if (!remainingTypes.length) {
resolve(populatedTypes);
return;
}
const type = remainingTypes.pop();
window.canvas = window.canvas || {};
window.canvas.register = d => registries[type].register(d);
window.canvas.i18n = i18n;
// Load plugins one at a time because each needs a different loader function
// $script will only load each of these once, we so can call this as many times as we need?
const pluginPath = `${basePath}/api/canvas/plugins?type=${type}`;
$script(pluginPath, () => {
populatedTypes[type] = registries[type];
loadType();
});
}
loadType();
});
};

View file

@ -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.
*/
// The server endpoint for retrieiving and running Canvas functions.
export const FUNCTIONS_URL = '/api/canvas/fns';

View file

@ -17,7 +17,7 @@
* under the License.
*/
export function createHandlers(/*socket*/) {
export function createHandlers() {
return {
environment: 'client',
};

View file

@ -17,7 +17,12 @@
* under the License.
*/
export { loadBrowserRegistries } from './browser_registries';
export { createSocket } from './socket';
export { initializeInterpreter } from './interpreter';
export { RenderFunctionsRegistry } from './render_functions_registry';
export { registries } from './registries';
import { registries } from './registries';
import { registryFactory } from '../common';
// Expose kbnInterpreter.register(specs) and kbnInterpreter.registries() globally so that plugins
// can register without a transpile step.
global.kbnInterpreter = Object.assign(global.kbnInterpreter || {}, registryFactory(registries));

View file

@ -17,55 +17,37 @@
* under the License.
*/
import { socketInterpreterProvider } from '../common/interpreter/socket_interpret';
import { interpreterProvider } from '../common/interpreter/interpret';
import { serializeProvider } from '../common/lib/serialize';
import { createHandlers } from './create_handlers';
import { batchedFetch } from './batched_fetch';
import { FUNCTIONS_URL } from './consts';
export async function initializeInterpreter(socket, typesRegistry, functionsRegistry) {
let resolve;
const functionList = new Promise(_resolve => (resolve = _resolve));
export async function initializeInterpreter(kfetch, typesRegistry, functionsRegistry) {
const serverFunctionList = await kfetch({ pathname: FUNCTIONS_URL });
const types = typesRegistry.toJS();
const { serialize } = serializeProvider(types);
const batch = batchedFetch({ kfetch, serialize });
const getInitializedFunctions = async () => {
return functionList;
};
// For every sever-side function, register a client-side
// function that matches its definition, but which simply
// calls the server-side function endpoint.
Object.keys(serverFunctionList).forEach(functionName => {
functionsRegistry.register(() => ({
...serverFunctionList[functionName],
fn: (context, args) => batch({ functionName, args, context }),
}));
});
const interpretAst = async (ast, context, handlers) => {
// Load plugins before attempting to get functions, otherwise this gets racey
const serverFunctionList = await functionList;
const interpretFn = await socketInterpreterProvider({
const interpretFn = await interpreterProvider({
types: typesRegistry.toJS(),
handlers: { ...handlers, ...createHandlers(socket) },
handlers: { ...handlers, ...createHandlers() },
functions: functionsRegistry.toJS(),
referableFunctions: serverFunctionList,
socket: socket,
});
return interpretFn(ast, context);
};
// Listen for interpreter runs
socket.on('run', ({ ast, context, id }) => {
const types = typesRegistry.toJS();
const { serialize, deserialize } = serializeProvider(types);
interpretAst(ast, deserialize(context)).then(value => {
socket.emit(`resp:${id}`, { value: serialize(value) });
});
});
// Create the function list
let gotFunctionList = false;
socket.once('functionList', (fl) => {
gotFunctionList = true;
resolve(fl);
});
const interval = setInterval(() => {
if (gotFunctionList) {
clearInterval(interval);
return;
}
socket.emit('getFunctionList');
}, 1000);
return { getInitializedFunctions, interpretAst };
return { interpretAst };
}

View file

@ -0,0 +1,98 @@
/*
* 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 { FUNCTIONS_URL } from './consts';
import { initializeInterpreter } from './interpreter';
jest.mock('../common/interpreter/interpret', () => ({
interpreterProvider: () => () => ({}),
}));
jest.mock('../common/lib/serialize', () => ({
serializeProvider: () => ({ serialize: () => ({}) }),
}));
jest.mock('./create_handlers', () => ({
createHandlers: () => ({}),
}));
describe('kbn-interpreter/interpreter', () => {
it('loads server-side functions', async () => {
const kfetch = jest.fn(async () => ({}));
await initializeInterpreter(kfetch, { toJS: () => ({}) }, ({ register: () => {} }));
expect(kfetch).toHaveBeenCalledTimes(1);
expect(kfetch).toHaveBeenCalledWith({ pathname: FUNCTIONS_URL });
});
it('registers client-side functions that pass through to the server', async () => {
const kfetch = jest.fn(async ({ method }) => {
if (method === 'POST') {
return {
results: [{
id: 1,
result: {
hello: 'world',
},
}],
};
}
return {
hello: { name: 'hello' },
world: { name: 'world' },
};
});
const register = jest.fn();
await initializeInterpreter(kfetch, { toJS: () => ({}) }, ({ register }));
expect(register).toHaveBeenCalledTimes(2);
const [ hello, world ] = register.mock.calls.map(([fn]) => fn());
expect(hello.name).toEqual('hello');
expect(typeof hello.fn).toEqual('function');
expect(world.name).toEqual('world');
expect(typeof world.fn).toEqual('function');
const context = {};
const args = { quote: 'All we have to decide is what to do with the time that is given us.' };
const result = await hello.fn(context, args);
expect(result).toEqual({ hello: 'world' });
expect(kfetch).toHaveBeenCalledWith({
pathname: FUNCTIONS_URL,
method: 'POST',
body: JSON.stringify({
functions: [{
id: 1,
functionName: 'hello',
args,
context,
}]
}),
});
});
});

View file

@ -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.
*/
import { register, FunctionsRegistry, TypesRegistry } from '../common';
import { RenderFunctionsRegistry } from './render_functions_registry';
import { browserFunctions } from '../plugin/functions/browser';
import { typeSpecs } from '../plugin/types';
export const registries = {
browserFunctions: new FunctionsRegistry(),
renderers: new RenderFunctionsRegistry(),
types: new TypesRegistry(),
};
register(registries, {
browserFunctions,
types: typeSpecs,
});

View file

@ -1,63 +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 io from 'socket.io-client';
const SOCKET_CONNECTION_TIMEOUT = 5000; // timeout in ms
export async function createSocket(basePath, functionsRegistry) {
return new Promise((resolve, reject) => {
const socket = io({
path: `${basePath}/socket.io`,
transports: ['polling', 'websocket'],
transportOptions: {
polling: {
extraHeaders: {
'kbn-xsrf': 'professionally-crafted-string-of-text',
},
},
},
timeout: SOCKET_CONNECTION_TIMEOUT,
// ensure socket.io always tries polling first, otherwise auth will fail
rememberUpgrade: false,
});
socket.on('getFunctionList', () => {
socket.emit('functionList', functionsRegistry.toJS());
});
socket.on('connect', () => {
resolve(socket);
socket.off('connectionFailed', errorHandler);
socket.off('connect_error', errorHandler);
socket.off('connect_timeout', errorHandler);
});
function errorHandler(err) {
// 'connectionFailed' returns an object with a reason prop
// other error cases provide their own error
reject(err.reason ? new Error(err.reason) : err);
}
socket.on('connectionFailed', errorHandler);
socket.on('connect_error', errorHandler);
socket.on('connect_timeout', errorHandler);
});
}

View file

@ -1,110 +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 path from 'path';
import fs from 'fs';
import { promisify } from 'util';
import { flatten } from 'lodash';
import { pluginPaths } from './plugin_paths';
const lstat = promisify(fs.lstat);
const readdir = promisify(fs.readdir);
const canvasPluginDirectoryName = 'canvas_plugin';
const isDirectory = path =>
lstat(path)
.then(stat => stat.isDirectory())
.catch(() => false); // if lstat fails, it doesn't exist and is not a directory
const isDirname = (p, name) => path.basename(p) === name;
const filterDirectories = (paths, { exclude = false } = {}) => {
return Promise.all(paths.map(p => isDirectory(p))).then(directories => {
return paths.filter((p, i) => (exclude ? !directories[i] : directories[i]));
});
};
const getPackagePluginPath = () => {
let basePluginPath = path.resolve(__dirname, '..');
if (isDirname(basePluginPath, 'target')) {
basePluginPath = path.join(basePluginPath, '..');
}
return basePluginPath;
};
const getKibanaPluginsPath = () => {
let kibanaPath = path.resolve(getPackagePluginPath(), '..', '..');
// in dev mode we are in kibana folder, else we are in node_modules
if (!isDirname(kibanaPath, 'kibana')) {
kibanaPath = path.join(kibanaPath, '..');
}
return path.join(kibanaPath, 'plugins');
};
const getXPackPluginsPath = () => {
const kibanaPath = path.resolve(getPackagePluginPath(), '..', '..');
// in dev mode we are in kibana folder, else we are in node_modules
return path.join(kibanaPath, 'x-pack/plugins');
};
// These must all exist
const paths = [
getPackagePluginPath(),
getXPackPluginsPath(), // Canvas core plugins
getKibanaPluginsPath(), // Kibana plugin directory
].filter(Boolean);
export const getPluginPaths = type => {
const typePath = pluginPaths[type];
if (!typePath) throw new Error(`Unknown type: ${type}`);
async function findPlugins(directory) {
const isDir = await isDirectory(directory);
if (!isDir) return;
const names = await readdir(directory); // Get names of everything in the directory
return names
.filter(name => name[0] !== '.')
.map(name => path.resolve(directory, name, canvasPluginDirectoryName, ...typePath));
}
return Promise.all(paths.map(findPlugins))
.then(dirs =>
dirs.reduce((list, dir) => {
if (!dir) return list;
return list.concat(dir);
}, [])
)
.then(possibleCanvasPlugins => filterDirectories(possibleCanvasPlugins, { exclude: false }))
.then(canvasPluginDirectories => {
return Promise.all(
canvasPluginDirectories.map(dir =>
// Get the full path of all files in the directory
readdir(dir).then(files => files.map(file => path.resolve(dir, file)))
)
)
.then(flatten)
.then(files => filterDirectories(files, { exclude: true }));
});
};

View file

@ -17,6 +17,14 @@
* under the License.
*/
export { populateServerRegistries } from './server_registries';
export { getPluginPaths } from './get_plugin_paths';
export { pluginPaths } from './plugin_paths';
import { typeSpecs as types } from '../plugin/types';
import { register, TypesRegistry, FunctionsRegistry } from '../common';
export const registries = {
types: new TypesRegistry(),
serverFunctions: new FunctionsRegistry(),
};
register(registries, {
types,
});

View file

@ -1,35 +0,0 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export const pluginPaths = {
serverFunctions: ['functions', 'server'],
browserFunctions: ['functions', 'browser'],
commonFunctions: ['functions', 'common'],
types: ['types'],
elements: ['elements'],
renderers: ['renderers'],
interfaces: ['interfaces'],
transformUIs: ['uis', 'transforms'],
datasourceUIs: ['uis', 'datasources'],
modelUIs: ['uis', 'models'],
viewUIs: ['uis', 'views'],
argumentUIs: ['uis', 'arguments'],
templates: ['templates'],
tagUIs: ['uis', 'tags'],
};

View file

@ -1,56 +0,0 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { i18n } from '@kbn/i18n';
import { getPluginPaths } from './get_plugin_paths';
export const populateServerRegistries = registries => {
if (!registries) throw new Error('registries are required');
return new Promise(resolve => {
const remainingTypes = Object.keys(registries);
const populatedTypes = {};
const loadType = () => {
const type = remainingTypes.pop();
getPluginPaths(type).then(paths => {
global.canvas = global.canvas || {};
global.canvas.register = d => registries[type].register(d);
global.canvas.i18n = i18n;
paths.forEach(path => {
require(path); // eslint-disable-line import/no-dynamic-require
});
delete global.canvas;
populatedTypes[type] = registries[type];
if (remainingTypes.length) {
loadType();
}
else {
resolve(populatedTypes);
}
});
};
if (remainingTypes.length) loadType();
});
};

View file

@ -26,7 +26,6 @@ const { ToolingLog, withProcRunner, pickLevelFromFlags } = require('@kbn/dev-uti
const {
ROOT_DIR,
PLUGIN_SOURCE_DIR,
BUILD_DIR,
WEBPACK_CONFIG_PATH
} = require('./paths');
@ -82,7 +81,7 @@ withProcRunner(log, async (proc) => {
cmd: 'babel',
args: [
'src',
'--ignore', `${relative(cwd, PLUGIN_SOURCE_DIR)},*.test.js`,
'--ignore', `*.test.js`,
'--out-dir', relative(cwd, BUILD_DIR),
'--copy-files',
...(flags.dev ? ['--source-maps', 'inline'] : []),

View file

@ -7,7 +7,6 @@ import { I18nProvider } from '@kbn/i18n/react';
<%_ } _%>
import 'ui/autoload/styles';
import './less/main.less';
import { Main } from './components/main';
const app = uiModules.get('apps/<%= camelCase(name) %>');

View file

@ -1,4 +0,0 @@
.container {
margin-top: 30px;
}

View file

@ -467,7 +467,7 @@ main {
border-bottom-left-radius: 4px; }
.kuiButtonGroup--united .kuiButton + .kuiButton {
margin-left: 2px; }
margin-left: 0; }
.kuiButtonGroup--fullWidth {
display: -webkit-box;

Some files were not shown because too many files have changed in this diff Show more