mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[merge] Merged with master.
This commit is contained in:
commit
87e68ab977
752 changed files with 10886 additions and 6947 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,4 +1,5 @@
|
|||
.aws-config.json
|
||||
.signing-config.json
|
||||
.ackrc
|
||||
.DS_Store
|
||||
.node_binaries
|
||||
|
|
|
@ -1 +1 @@
|
|||
4.3.2
|
||||
4.4.4
|
||||
|
|
|
@ -55,7 +55,7 @@ Please make sure you have signed the [Contributor License Agreement](http://www.
|
|||
npm run elasticsearch
|
||||
```
|
||||
|
||||
- Start the development server. _On Windows, you'll need you use Git Bash, Cygwin, or a similar shell that exposes the `sh` command._
|
||||
- Start the development server. _On Windows, you'll need you use Git Bash, Cygwin, or a similar shell that exposes the `sh` command. And to successfully build you'll need Cygwin optional packages zip, tar, and shasum._
|
||||
|
||||
```sh
|
||||
npm start
|
||||
|
@ -209,8 +209,8 @@ Then sit back and wait. There will probably be discussion about the pull request
|
|||
|
||||
After a pull is submitted, it needs to get to review. If you have commit permission on the Kibana repo you will probably perform these steps while submitting your pull request. If not, a member of the elastic organization will do them for you, though you can help by suggesting a reviewer for your changes if you've interacted with someone while working on the issue.
|
||||
|
||||
1. Assign the `review` tag. This signals to the team that someone needs to give this attention.
|
||||
1. Assign version tags. If the pull is related to an existing issue (and it should be!), that issue probably has a version tag (eg `4.0.1`) on it. Assign the same version tag to your pull. You may end up with 2 or more version tags if the changes requires backporting
|
||||
1. Assign the `review` label. This signals to the team that someone needs to give this attention.
|
||||
1. Do **not** assign a version label. Someone from Elastic staff will assign a version label, if necessary, when your pull request is ready to be merged.
|
||||
1. Find someone to review your pull. Don't just pick any yahoo, pick the right person. The right person might be the original reporter of the issue, but it might also be the person most familiar with the code you've changed. If neither of those things apply, or your change is small in scope, try to find someone on the Kibana team without a ton of existing reviews on their plate. As a rule, most pulls will require 2 reviewers, but the first reviewer will pick the 2nd.
|
||||
|
||||
### Review engaged
|
||||
|
|
|
@ -62,7 +62,8 @@ module.exports = function (grunt) {
|
|||
'postcss-unique-selectors': '1.0.0',
|
||||
'postcss-minify-selectors': '1.4.6',
|
||||
'postcss-single-charset': '0.3.0',
|
||||
'regenerator': '0.8.36'
|
||||
'regenerator': '0.8.36',
|
||||
'readable-stream': '2.1.0'
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -88,4 +89,5 @@ module.exports = function (grunt) {
|
|||
// load task definitions
|
||||
grunt.task.loadTasks('tasks');
|
||||
grunt.task.loadTasks('tasks/build');
|
||||
grunt.task.loadTasks('tasks/rebuild');
|
||||
};
|
||||
|
|
12
README.md
12
README.md
|
@ -41,9 +41,9 @@ Visit [Elastic.co](http://www.elastic.co/guide/en/kibana/current/index.html) for
|
|||
|
||||
For the daring, snapshot builds are available. These builds are created after each commit to the master branch, and therefore are not something you should run in production.
|
||||
|
||||
| platform | | |
|
||||
| --- | --- | --- |
|
||||
| OSX | [tar](http://download.elastic.co/kibana/kibana-snapshot/kibana-5.0.0-snapshot-darwin-x64.tar.gz) | [zip](http://download.elastic.co/kibana/kibana-snapshot/kibana-5.0.0-snapshot-darwin-x64.zip) |
|
||||
| Linux x64 | [tar](http://download.elastic.co/kibana/kibana-snapshot/kibana-5.0.0-snapshot-linux-x64.tar.gz) | [zip](http://download.elastic.co/kibana/kibana-snapshot/kibana-5.0.0-snapshot-linux-x64.zip) |
|
||||
| Linux x86 | [tar](http://download.elastic.co/kibana/kibana-snapshot/kibana-5.0.0-snapshot-linux-x86.tar.gz) | [zip](http://download.elastic.co/kibana/kibana-snapshot/kibana-5.0.0-snapshot-linux-x86.zip) |
|
||||
| Windows | [tar](http://download.elastic.co/kibana/kibana-snapshot/kibana-5.0.0-snapshot-windows.tar.gz) | [zip](http://download.elastic.co/kibana/kibana-snapshot/kibana-5.0.0-snapshot-windows.zip) |
|
||||
| platform | | | | |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| OSX | [tar](http://download.elastic.co/kibana/kibana-snapshot/kibana-5.0.0-snapshot-darwin-x64.tar.gz) | [zip](http://download.elastic.co/kibana/kibana-snapshot/kibana-5.0.0-snapshot-darwin-x64.zip) | | |
|
||||
| Linux x64 | [tar](http://download.elastic.co/kibana/kibana-snapshot/kibana-5.0.0-snapshot-linux-x64.tar.gz) | [zip](http://download.elastic.co/kibana/kibana-snapshot/kibana-5.0.0-snapshot-linux-x64.zip) | [deb](https://download.elastic.co/kibana/kibana-snapshot/kibana_5.0.0-snapshot_amd64.deb)| [rpm](https://download.elastic.co/kibana/kibana-snapshot/kibana-5.0.0_snapshot-1.x86_64.rpm) |
|
||||
| Linux x86 | [tar](http://download.elastic.co/kibana/kibana-snapshot/kibana-5.0.0-snapshot-linux-x86.tar.gz) | [zip](http://download.elastic.co/kibana/kibana-snapshot/kibana-5.0.0-snapshot-linux-x86.zip) | [deb](https://download.elastic.co/kibana/kibana-snapshot/kibana_5.0.0-snapshot_i386.deb) | [rpm](https://download.elastic.co/kibana/kibana-snapshot/kibana-5.0.0_snapshot-1.i386.rpm) |
|
||||
| Windows | [tar](http://download.elastic.co/kibana/kibana-snapshot/kibana-5.0.0-snapshot-windows.tar.gz) | [zip](http://download.elastic.co/kibana/kibana-snapshot/kibana-5.0.0-snapshot-windows.zip) | | |
|
||||
|
|
|
@ -61,6 +61,10 @@
|
|||
# must be a positive integer.
|
||||
# elasticsearch.requestTimeout: 30000
|
||||
|
||||
# List of Kibana client-side headers to send to Elasticsearch. To send *no* client-side
|
||||
# headers, set this value to [] (an empty list).
|
||||
# elasticsearch.requestHeadersWhitelist: [ authorization ]
|
||||
|
||||
# Time in milliseconds for Elasticsearch to wait for responses from shards. Set to 0 to disable.
|
||||
# elasticsearch.shardTimeout: 0
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
[[kibana-settings-reference]]
|
||||
|
||||
WARNING: Modifying the following settings can signficantly 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
|
||||
WARNING: Modifying the following settings can signficantly 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
|
||||
|
@ -10,38 +10,39 @@ compatible with other configuration settings. Deleting a custom setting removes
|
|||
`sort:options`:: Options for the Elasticsearch https://www.elastic.co/guide/en/elasticsearch/reference/current/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.
|
||||
`dateFormat:scaled`:: These values define the format used to render ordered time-based data. Formatted timestamps must
|
||||
`dateFormat:scaled`:: These values define the format used to render ordered time-based data. Formatted timestamps must
|
||||
`dateFormat:dow`:: This property defines what day weeks should start on.
|
||||
adapt to the interval between measurements. Keys are http://en.wikipedia.org/wiki/ISO_8601#Time_intervals[ISO8601 intervals].
|
||||
`defaultIndex`:: Default is `null`. This property specifies the default index.
|
||||
`metaFields`:: An array of fields outside of `_source`. Kibana merges these fields into the document when displaying the
|
||||
`metaFields`:: An array of fields outside of `_source`. Kibana merges these fields into the document when displaying the
|
||||
document.
|
||||
`defaultColumns`:: Default is `_source`. Defines the columns that appear by default on the Discover page.
|
||||
`discover:sampleSize`:: The number of rows to show in the Discover table.
|
||||
`doc_table:highlight`:: Highlight results in Discover and Saved Searches Dashboard. Highlighing makes request slow when
|
||||
`doc_table:highlight`:: Highlight results in Discover and Saved Searches Dashboard. Highlighing makes request slow when
|
||||
working on big documents. Set this property to `false` to disable highlighting.
|
||||
`courier:maxSegmentCount`:: Kibana splits requests in the Discover app into segments to limit the size of requests sent to
|
||||
the Elasticsearch cluster. This setting constrains the length of the segment list. Long segment lists can significantly
|
||||
`courier:maxSegmentCount`:: Kibana splits requests in the Discover app into segments to limit the size of requests sent to
|
||||
the Elasticsearch cluster. This setting constrains the length of the segment list. Long segment lists can significantly
|
||||
increase request processing time.
|
||||
`fields:popularLimit`:: This setting governs how many of the top most popular fields are shown.
|
||||
`histogram:barTarget`:: When date histograms use the `auto` interval, Kibana attempts to generate this number of bars.
|
||||
`histogram:maxBars`:: Date histograms are not generated with more bars than the value of this property, scaling values
|
||||
`histogram:maxBars`:: Date histograms are not generated with more bars than the value of this property, scaling values
|
||||
when necessary.
|
||||
`visualization:tileMap:maxPrecision`:: The maximum geoHash precision displayed on tile maps: 7 is high, 10 is very high,
|
||||
`visualization:tileMap:maxPrecision`:: The maximum geoHash precision displayed on tile maps: 7 is high, 10 is very high,
|
||||
12 is the maximum. http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-geohashgrid-aggregation.html#_cell_dimensions_at_the_equator[Explanation of cell dimensions].
|
||||
`visualization:tileMap:WMSdefaults`:: Default properties for the WMS map server support in the tile map.
|
||||
`visualization:colorMapping`:: Maps values to specified colors within visualizations.
|
||||
`visualization:loadingDelay`:: Time to wait before dimming visualizations during query.
|
||||
`csv:separator`:: A string that serves as the separator for exported values.
|
||||
`csv:quoteValues`:: Set this property to `true` to quote exported values.
|
||||
`history:limit`:: In fields that have history, such as query inputs, the value of this property limits how many recent
|
||||
`history:limit`:: In fields that have history, such as query inputs, the value of this property limits how many recent
|
||||
values are shown.
|
||||
`shortDots:enable`:: Set this property to `true` to shorten long field names in visualizations. For example, instead of
|
||||
`shortDots:enable`:: Set this property to `true` to shorten long field names in visualizations. For example, instead of
|
||||
`foo.bar.baz`, show `f.b.baz`.
|
||||
`truncate:maxHeight`:: This property specifies the maximum height that a cell occupies in a table. A value of 0 disables
|
||||
`truncate:maxHeight`:: This property specifies the maximum height that a cell occupies in a table. A value of 0 disables
|
||||
truncation.
|
||||
`indexPattern:fieldMapping:lookBack`:: The value of this property sets the number of recent matching patterns to query the
|
||||
`indexPattern:fieldMapping:lookBack`:: The value of this property sets the number of recent matching patterns to query the
|
||||
field mapping for index patterns with names that contain timestamps.
|
||||
`format:defaultTypeMap`:: A map of the default format name for each field type. Field types that are not explicitly
|
||||
`format:defaultTypeMap`:: A map of the default format name for each field type. Field types that are not explicitly
|
||||
mentioned use "_default_".
|
||||
`format:number:defaultPattern`:: Default numeral format for the "number" format.
|
||||
`format:bytes:defaultPattern`:: Default numeral format for the "bytes" format.
|
||||
|
|
|
@ -36,9 +36,7 @@ include::color-picker.asciidoc[]
|
|||
You can click the *Advanced* link to display more customization options for your metrics or bucket aggregation:
|
||||
|
||||
*Exclude Pattern*:: Specify a pattern in this field to exclude from the results.
|
||||
*Exclude Pattern Flags*:: A standard set of Java flags for the exclusion pattern.
|
||||
*Include Pattern*:: Specify a pattern in this field to include in the results.
|
||||
*Include Pattern Flags*:: A standard set of Java flags for the inclusion pattern.
|
||||
*JSON Input*:: A text field where you can add specific JSON-formatted properties to merge with the aggregation
|
||||
definition, as in the following example:
|
||||
|
||||
|
|
|
@ -50,9 +50,7 @@ Enter a string in the *Custom Label* field to change the display label.
|
|||
You can click the *Advanced* link to display more customization options for your metrics or bucket aggregation:
|
||||
|
||||
*Exclude Pattern*:: Specify a pattern in this field to exclude from the results.
|
||||
*Exclude Pattern Flags*:: A standard set of Java flags for the exclusion pattern.
|
||||
*Include Pattern*:: Specify a pattern in this field to include in the results.
|
||||
*Include Pattern Flags*:: A standard set of Java flags for the inclusion pattern.
|
||||
*JSON Input*:: A text field where you can add specific JSON-formatted properties to merge with the aggregation
|
||||
definition, as in the following example:
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ key Kibana functionality. By the end of this tutorial, you will have:
|
|||
|
||||
* Loaded a sample data set into your Elasticsearch installation
|
||||
* Defined at least one index pattern
|
||||
* Use the <<discover, Discover>> functionality to explore your data
|
||||
* Used the <<discover, Discover>> functionality to explore your data
|
||||
* Set up some <<visualize,_visualizations_>> to graphically represent your data
|
||||
* Assembled visualizations into a <<dashboard,Dashboard>>
|
||||
|
||||
|
|
|
@ -29,7 +29,9 @@ to `false`.
|
|||
wait for Elasticsearch to respond to pings.
|
||||
`elasticsearch.requestTimeout:`:: *Default: 300000* Time in milliseconds to wait for responses from the back end or
|
||||
Elasticsearch. This value must be a positive integer.
|
||||
`elasticsearch.shardTimeout:`:: *Default: 0* Time in milliseconds for Elasticsearch to wait for responses from shards. Set
|
||||
`elasticsearch.requestHeadersWhitelist:`:: *Default: `[ 'authorization' ]`* List of Kibana client-side headers to send to Elasticsearch.
|
||||
To send *no* client-side headers, set this value to [] (an empty list).
|
||||
`elasticsearch.shardTimeout:`:: *Default: 0* Time in milliseconds for Elasticsearch to wait for responses from shards. Set
|
||||
to 0 to disable.
|
||||
`elasticsearch.startupTimeout:`:: *Default: 5000* Time in milliseconds to wait for Elasticsearch at Kibana startup before
|
||||
retrying.
|
||||
|
@ -42,3 +44,5 @@ error messages.
|
|||
information and all requests.
|
||||
`ops.interval`:: *Default: 10000* Set the interval in milliseconds to sample system and process performance metrics.
|
||||
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.
|
||||
|
|
|
@ -64,9 +64,7 @@ Enter a string in the *Custom Label* field to change the display label.
|
|||
You can click the *Advanced* link to display more customization options for your metrics or bucket aggregation:
|
||||
|
||||
*Exclude Pattern*:: Specify a pattern in this field to exclude from the results.
|
||||
*Exclude Pattern Flags*:: A standard set of Java flags for the exclusion pattern.
|
||||
*Include Pattern*:: Specify a pattern in this field to include in the results.
|
||||
*Include Pattern Flags*:: A standard set of Java flags for the inclusion pattern.
|
||||
*JSON Input*:: A text field where you can add specific JSON-formatted properties to merge with the aggregation
|
||||
definition, as in the following example:
|
||||
|
||||
|
|
|
@ -376,6 +376,10 @@ deprecated[4.2, The names of several Kibana server properties changed in the 4.2
|
|||
+
|
||||
*default*: `500000`
|
||||
|
||||
`elasticsearch.requestHeadersWhitelist:` added[5.0]:: List of Kibana client-side headers to send to Elasticsearch. To send *no* client-side headers, set this value to [] (an empty list).
|
||||
+
|
||||
*default*: `[ 'authorization' ]`
|
||||
|
||||
`elasticsearch.shardTimeout` added[4.2]:: How long Elasticsearch should wait for responses from shards. Set to 0 to disable.
|
||||
+
|
||||
*alias*: `shard_timeout` deprecated[4.2]
|
||||
|
|
|
@ -78,9 +78,7 @@ Enter a string in the *Custom Label* field to change the display label.
|
|||
You can click the *Advanced* link to display more customization options for your metrics or bucket aggregation:
|
||||
|
||||
*Exclude Pattern*:: Specify a pattern in this field to exclude from the results.
|
||||
*Exclude Pattern Flags*:: A standard set of Java flags for the exclusion pattern.
|
||||
*Include Pattern*:: Specify a pattern in this field to include in the results.
|
||||
*Include Pattern Flags*:: A standard set of Java flags for the inclusion pattern.
|
||||
*JSON Input*:: A text field where you can add specific JSON-formatted properties to merge with the aggregation
|
||||
definition, as in the following example:
|
||||
|
||||
|
|
|
@ -43,9 +43,7 @@ Enter a string in the *Custom Label* field to change the display label.
|
|||
You can click the *Advanced* link to display more customization options for your metrics or bucket aggregation:
|
||||
|
||||
*Exclude Pattern*:: Specify a pattern in this field to exclude from the results.
|
||||
*Exclude Pattern Flags*:: A standard set of Java flags for the exclusion pattern.
|
||||
*Include Pattern*:: Specify a pattern in this field to include in the results.
|
||||
*Include Pattern Flags*:: A standard set of Java flags for the inclusion pattern.
|
||||
*JSON Input*:: A text field where you can add specific JSON-formatted properties to merge with the aggregation
|
||||
definition, as in the following example:
|
||||
|
||||
|
|
11
package.json
11
package.json
|
@ -16,7 +16,6 @@
|
|||
"number": 8467,
|
||||
"sha": "6cb7fec4e154faa0a4a3fee4b33dfef91b9870d9"
|
||||
},
|
||||
"main": "src/server/KbnServer.js",
|
||||
"homepage": "https://www.elastic.co/products/kibana",
|
||||
"bugs": {
|
||||
"url": "http://github.com/elastic/kibana/issues"
|
||||
|
@ -68,6 +67,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@bigfunger/decompress-zip": "0.2.0-stripfix2",
|
||||
"@elastic/datemath": "2.2.0",
|
||||
"@spalger/angular-bootstrap": "0.12.1",
|
||||
"@spalger/filesaver": "1.1.2",
|
||||
"@spalger/leaflet-draw": "0.2.3",
|
||||
|
@ -127,9 +127,11 @@
|
|||
"mkdirp": "0.5.1",
|
||||
"moment": "2.10.6",
|
||||
"moment-timezone": "0.4.1",
|
||||
"node-uuid": "1.4.7",
|
||||
"raw-loader": "0.5.1",
|
||||
"request": "2.61.0",
|
||||
"rimraf": "2.4.3",
|
||||
"rison-node": "1.0.0",
|
||||
"rjs-repack-loader": "1.0.6",
|
||||
"script-loader": "0.6.1",
|
||||
"semver": "5.1.0",
|
||||
|
@ -145,7 +147,7 @@
|
|||
"wreck": "6.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@elastic/eslint-config-kibana": "0.0.2",
|
||||
"@elastic/eslint-config-kibana": "0.0.3",
|
||||
"Nonsense": "0.1.2",
|
||||
"angular-mocks": "1.4.7",
|
||||
"auto-release-sinon": "1.0.3",
|
||||
|
@ -189,10 +191,11 @@
|
|||
"simple-git": "1.8.0",
|
||||
"sinon": "1.17.2",
|
||||
"source-map": "0.4.4",
|
||||
"source-map-support": "0.4.0",
|
||||
"supertest-as-promised": "2.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": "4.3.2",
|
||||
"npm": "2.14.22"
|
||||
"node": "4.4.4",
|
||||
"npm": "2.15.1"
|
||||
}
|
||||
}
|
||||
|
|
48
src/cli/serve/__tests__/deprecated_config.js
Normal file
48
src/cli/serve/__tests__/deprecated_config.js
Normal file
|
@ -0,0 +1,48 @@
|
|||
import expect from 'expect.js';
|
||||
import { set } from 'lodash';
|
||||
import { checkForDeprecatedConfig } from '../deprecated_config';
|
||||
import sinon from 'auto-release-sinon';
|
||||
|
||||
describe('cli/serve/deprecated_config', function () {
|
||||
it('passes original config through', function () {
|
||||
const config = {};
|
||||
set(config, 'server.xsrf.token', 'xxtokenxx');
|
||||
const output = checkForDeprecatedConfig(config);
|
||||
expect(output).to.be(config);
|
||||
expect(output.server).to.be(config.server);
|
||||
expect(output.server.xsrf).to.be(config.server.xsrf);
|
||||
expect(output.server.xsrf.token).to.be(config.server.xsrf.token);
|
||||
});
|
||||
|
||||
it('logs warnings about deprecated config values', function () {
|
||||
const log = sinon.stub();
|
||||
const config = {};
|
||||
set(config, 'server.xsrf.token', 'xxtokenxx');
|
||||
checkForDeprecatedConfig(config, log);
|
||||
sinon.assert.calledOnce(log);
|
||||
expect(log.firstCall.args[0]).to.match(/server\.xsrf\.token.+deprecated/);
|
||||
});
|
||||
|
||||
describe('does not support compound.keys', function () {
|
||||
it('ignores fully compound keys', function () {
|
||||
const log = sinon.stub();
|
||||
const config = { 'server.xsrf.token': 'xxtokenxx' };
|
||||
checkForDeprecatedConfig(config, log);
|
||||
sinon.assert.notCalled(log);
|
||||
});
|
||||
|
||||
it('ignores partially compound keys', function () {
|
||||
const log = sinon.stub();
|
||||
const config = { server: { 'xsrf.token': 'xxtokenxx' } };
|
||||
checkForDeprecatedConfig(config, log);
|
||||
sinon.assert.notCalled(log);
|
||||
});
|
||||
|
||||
it('ignores partially compound keys', function () {
|
||||
const log = sinon.stub();
|
||||
const config = { 'server.xsrf': { token: 'xxtokenxx' } };
|
||||
checkForDeprecatedConfig(config, log);
|
||||
sinon.assert.notCalled(log);
|
||||
});
|
||||
});
|
||||
});
|
1
src/cli/serve/__tests__/fixtures/deprecated.yml
Normal file
1
src/cli/serve/__tests__/fixtures/deprecated.yml
Normal file
|
@ -0,0 +1 @@
|
|||
server.xsrf.token: token
|
1
src/cli/serve/__tests__/fixtures/legacy.yml
Normal file
1
src/cli/serve/__tests__/fixtures/legacy.yml
Normal file
|
@ -0,0 +1 @@
|
|||
kibana_index: indexname
|
2
src/cli/serve/__tests__/fixtures/one.yml
Normal file
2
src/cli/serve/__tests__/fixtures/one.yml
Normal file
|
@ -0,0 +1,2 @@
|
|||
foo: 1
|
||||
bar: true
|
2
src/cli/serve/__tests__/fixtures/two.yml
Normal file
2
src/cli/serve/__tests__/fixtures/two.yml
Normal file
|
@ -0,0 +1,2 @@
|
|||
foo: 2
|
||||
baz: bonkers
|
28
src/cli/serve/__tests__/legacy_config.js
Normal file
28
src/cli/serve/__tests__/legacy_config.js
Normal file
|
@ -0,0 +1,28 @@
|
|||
import expect from 'expect.js';
|
||||
import { rewriteLegacyConfig } from '../legacy_config';
|
||||
import sinon from 'auto-release-sinon';
|
||||
|
||||
describe('cli/serve/legacy_config', function () {
|
||||
it('returns a clone of the input', function () {
|
||||
const file = {};
|
||||
const output = rewriteLegacyConfig(file);
|
||||
expect(output).to.not.be(file);
|
||||
});
|
||||
|
||||
it('rewrites legacy config values with literal path replacement', function () {
|
||||
const file = { port: 4000, host: 'kibana.com' };
|
||||
const output = rewriteLegacyConfig(file);
|
||||
expect(output).to.not.be(file);
|
||||
expect(output).to.eql({
|
||||
'server.port': 4000,
|
||||
'server.host': 'kibana.com',
|
||||
});
|
||||
});
|
||||
|
||||
it('logs warnings when legacy config properties are encountered', function () {
|
||||
const log = sinon.stub();
|
||||
rewriteLegacyConfig({ port: 5555 }, log);
|
||||
sinon.assert.calledOnce(log);
|
||||
expect(log.firstCall.args[0]).to.match(/port.+deprecated.+server\.port/);
|
||||
});
|
||||
});
|
102
src/cli/serve/__tests__/read_yaml_config.js
Normal file
102
src/cli/serve/__tests__/read_yaml_config.js
Normal file
|
@ -0,0 +1,102 @@
|
|||
import expect from 'expect.js';
|
||||
import { join, relative, resolve } from 'path';
|
||||
import readYamlConfig from '../read_yaml_config';
|
||||
import sinon from 'auto-release-sinon';
|
||||
|
||||
function fixture(name) {
|
||||
return resolve(__dirname, 'fixtures', name);
|
||||
}
|
||||
|
||||
describe('cli/serve/read_yaml_config', function () {
|
||||
it('reads a single config file', function () {
|
||||
const config = readYamlConfig(fixture('one.yml'));
|
||||
|
||||
expect(readYamlConfig(fixture('one.yml'))).to.eql({
|
||||
foo: 1,
|
||||
bar: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('reads and merged mulitple config file', function () {
|
||||
const config = readYamlConfig([
|
||||
fixture('one.yml'),
|
||||
fixture('two.yml')
|
||||
]);
|
||||
|
||||
expect(config).to.eql({
|
||||
foo: 2,
|
||||
bar: true,
|
||||
baz: 'bonkers'
|
||||
});
|
||||
});
|
||||
|
||||
context('different cwd()', function () {
|
||||
const oldCwd = process.cwd();
|
||||
const newCwd = join(oldCwd, '..');
|
||||
|
||||
before(function () {
|
||||
process.chdir(newCwd);
|
||||
});
|
||||
|
||||
it('resolves relative files based on the cwd', function () {
|
||||
const relativePath = relative(newCwd, fixture('one.yml'));
|
||||
const config = readYamlConfig(relativePath);
|
||||
expect(config).to.eql({
|
||||
foo: 1,
|
||||
bar: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('fails to load relative paths, not found because of the cwd', function () {
|
||||
expect(function () {
|
||||
readYamlConfig(relative(oldCwd, fixture('one.yml')));
|
||||
}).to.throwException(/ENOENT/);
|
||||
});
|
||||
|
||||
after(function () {
|
||||
process.chdir(oldCwd);
|
||||
});
|
||||
});
|
||||
|
||||
context('stubbed stdout', function () {
|
||||
let stub;
|
||||
|
||||
beforeEach(function () {
|
||||
stub = sinon.stub(process.stdout, 'write');
|
||||
});
|
||||
|
||||
context('deprecated settings', function () {
|
||||
it('warns about deprecated settings', function () {
|
||||
readYamlConfig(fixture('deprecated.yml'));
|
||||
sinon.assert.calledOnce(stub);
|
||||
expect(stub.firstCall.args[0]).to.match(/deprecated/);
|
||||
stub.restore();
|
||||
});
|
||||
|
||||
it('only warns once about deprecated settings', function () {
|
||||
readYamlConfig(fixture('deprecated.yml'));
|
||||
readYamlConfig(fixture('deprecated.yml'));
|
||||
readYamlConfig(fixture('deprecated.yml'));
|
||||
sinon.assert.notCalled(stub); // already logged in previous test
|
||||
stub.restore();
|
||||
});
|
||||
});
|
||||
|
||||
context('legacy settings', function () {
|
||||
it('warns about deprecated settings', function () {
|
||||
readYamlConfig(fixture('legacy.yml'));
|
||||
sinon.assert.calledOnce(stub);
|
||||
expect(stub.firstCall.args[0]).to.match(/has been replaced/);
|
||||
stub.restore();
|
||||
});
|
||||
|
||||
it('only warns once about legacy settings', function () {
|
||||
readYamlConfig(fixture('legacy.yml'));
|
||||
readYamlConfig(fixture('legacy.yml'));
|
||||
readYamlConfig(fixture('legacy.yml'));
|
||||
sinon.assert.notCalled(stub); // already logged in previous test
|
||||
stub.restore();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
16
src/cli/serve/deprecated_config.js
Normal file
16
src/cli/serve/deprecated_config.js
Normal file
|
@ -0,0 +1,16 @@
|
|||
import { forOwn, has, noop } from 'lodash';
|
||||
|
||||
// deprecated settings are still allowed, but will be removed at a later time. They
|
||||
// are checked for after the config object is prepared and known, so legacySettings
|
||||
// will have already been transformed.
|
||||
export const deprecatedSettings = new Map([
|
||||
[['server', 'xsrf', 'token'], 'server.xsrf.token is deprecated. It is no longer used when providing xsrf protection.']
|
||||
]);
|
||||
|
||||
// check for and warn about deprecated settings
|
||||
export function checkForDeprecatedConfig(object, log = noop) {
|
||||
for (const [key, msg] of deprecatedSettings.entries()) {
|
||||
if (has(object, key)) log(msg);
|
||||
}
|
||||
return object;
|
||||
}
|
47
src/cli/serve/legacy_config.js
Normal file
47
src/cli/serve/legacy_config.js
Normal file
|
@ -0,0 +1,47 @@
|
|||
import { noop, transform } from 'lodash';
|
||||
|
||||
// legacySettings allow kibana 4.2+ to accept the same config file that people
|
||||
// used for kibana 4.0 and 4.1. These settings are transformed to their modern
|
||||
// equivalents at the very begining of the process
|
||||
export const legacySettings = {
|
||||
// server
|
||||
port: 'server.port',
|
||||
host: 'server.host',
|
||||
pid_file: 'pid.file',
|
||||
ssl_cert_file: 'server.ssl.cert',
|
||||
ssl_key_file: 'server.ssl.key',
|
||||
|
||||
// logging
|
||||
log_file: 'logging.dest',
|
||||
|
||||
// kibana
|
||||
kibana_index: 'kibana.index',
|
||||
default_app_id: 'kibana.defaultAppId',
|
||||
|
||||
// es
|
||||
ca: 'elasticsearch.ssl.ca',
|
||||
elasticsearch_preserve_host: 'elasticsearch.preserveHost',
|
||||
elasticsearch_url: 'elasticsearch.url',
|
||||
kibana_elasticsearch_client_crt: 'elasticsearch.ssl.cert',
|
||||
kibana_elasticsearch_client_key: 'elasticsearch.ssl.key',
|
||||
kibana_elasticsearch_password: 'elasticsearch.password',
|
||||
kibana_elasticsearch_username: 'elasticsearch.username',
|
||||
ping_timeout: 'elasticsearch.pingTimeout',
|
||||
request_timeout: 'elasticsearch.requestTimeout',
|
||||
shard_timeout: 'elasticsearch.shardTimeout',
|
||||
startup_timeout: 'elasticsearch.startupTimeout',
|
||||
verify_ssl: 'elasticsearch.ssl.verify',
|
||||
};
|
||||
|
||||
// transform legacy options into new namespaced versions
|
||||
export function rewriteLegacyConfig(object, log = noop) {
|
||||
return transform(object, (clone, val, key) => {
|
||||
if (legacySettings.hasOwnProperty(key)) {
|
||||
const replacement = legacySettings[key];
|
||||
log(`Config key "${key}" is deprecated. It has been replaced with "${replacement}"`);
|
||||
clone[replacement] = val;
|
||||
} else {
|
||||
clone[key] = val;
|
||||
}
|
||||
}, {});
|
||||
}
|
|
@ -1,75 +1,40 @@
|
|||
import _ from 'lodash';
|
||||
import fs from 'fs';
|
||||
import yaml from 'js-yaml';
|
||||
import { chain, isArray, isPlainObject, forOwn, memoize, set, transform } from 'lodash';
|
||||
import { readFileSync as read } from 'fs';
|
||||
import { safeLoad } from 'js-yaml';
|
||||
import { red } from 'ansicolors';
|
||||
|
||||
import { fromRoot } from '../../utils';
|
||||
import { rewriteLegacyConfig } from './legacy_config';
|
||||
import { checkForDeprecatedConfig } from './deprecated_config';
|
||||
|
||||
let legacySettingMap = {
|
||||
// server
|
||||
port: 'server.port',
|
||||
host: 'server.host',
|
||||
pid_file: 'pid.file',
|
||||
ssl_cert_file: 'server.ssl.cert',
|
||||
ssl_key_file: 'server.ssl.key',
|
||||
const log = memoize(function (message) {
|
||||
console.log(red('WARNING:'), message);
|
||||
});
|
||||
|
||||
// logging
|
||||
log_file: 'logging.dest',
|
||||
export function merge(sources) {
|
||||
return transform(sources, (merged, source) => {
|
||||
forOwn(source, function apply(val, key) {
|
||||
if (isPlainObject(val)) {
|
||||
forOwn(val, function (subVal, subKey) {
|
||||
apply(subVal, key + '.' + subKey);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// kibana
|
||||
kibana_index: 'kibana.index',
|
||||
default_app_id: 'kibana.defaultAppId',
|
||||
if (isArray(val)) {
|
||||
set(merged, key, []);
|
||||
val.forEach((subVal, i) => apply(subVal, key + '.' + i));
|
||||
return;
|
||||
}
|
||||
|
||||
// es
|
||||
ca: 'elasticsearch.ssl.ca',
|
||||
elasticsearch_preserve_host: 'elasticsearch.preserveHost',
|
||||
elasticsearch_url: 'elasticsearch.url',
|
||||
kibana_elasticsearch_client_crt: 'elasticsearch.ssl.cert',
|
||||
kibana_elasticsearch_client_key: 'elasticsearch.ssl.key',
|
||||
kibana_elasticsearch_password: 'elasticsearch.password',
|
||||
kibana_elasticsearch_username: 'elasticsearch.username',
|
||||
ping_timeout: 'elasticsearch.pingTimeout',
|
||||
request_timeout: 'elasticsearch.requestTimeout',
|
||||
shard_timeout: 'elasticsearch.shardTimeout',
|
||||
startup_timeout: 'elasticsearch.startupTimeout',
|
||||
verify_ssl: 'elasticsearch.ssl.verify',
|
||||
};
|
||||
|
||||
const deprecatedSettings = {
|
||||
'server.xsrf.token': 'server.xsrf.token is deprecated. It is no longer used when providing xsrf protection.'
|
||||
};
|
||||
|
||||
module.exports = function (path) {
|
||||
if (!path) return {};
|
||||
|
||||
let file = yaml.safeLoad(fs.readFileSync(path, 'utf8'));
|
||||
|
||||
function apply(config, val, key) {
|
||||
if (_.isPlainObject(val)) {
|
||||
_.forOwn(val, function (subVal, subKey) {
|
||||
apply(config, subVal, key + '.' + subKey);
|
||||
});
|
||||
}
|
||||
else if (_.isArray(val)) {
|
||||
config[key] = [];
|
||||
val.forEach((subVal, i) => {
|
||||
apply(config, subVal, key + '.' + i);
|
||||
});
|
||||
}
|
||||
else {
|
||||
_.set(config, key, val);
|
||||
}
|
||||
}
|
||||
|
||||
_.each(deprecatedSettings, function (message, setting) {
|
||||
if (_.has(file, setting)) console.error(message);
|
||||
});
|
||||
|
||||
// transform legeacy options into new namespaced versions
|
||||
return _.transform(file, function (config, val, key) {
|
||||
if (legacySettingMap.hasOwnProperty(key)) {
|
||||
key = legacySettingMap[key];
|
||||
}
|
||||
|
||||
apply(config, val, key);
|
||||
set(merged, key, val);
|
||||
});
|
||||
}, {});
|
||||
};
|
||||
}
|
||||
|
||||
export default function (paths) {
|
||||
const files = [].concat(paths || []);
|
||||
const yamls = files.map(path => safeLoad(read(path, 'utf8')));
|
||||
const config = merge(yamls.map(file => rewriteLegacyConfig(file, log)));
|
||||
return checkForDeprecatedConfig(config, log);
|
||||
}
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
import _ from 'lodash';
|
||||
const { isWorker } = require('cluster');
|
||||
const { resolve } = require('path');
|
||||
import { statSync } from 'fs';
|
||||
import { isWorker } from 'cluster';
|
||||
import { resolve } from 'path';
|
||||
|
||||
import readYamlConfig from './read_yaml_config';
|
||||
import { fromRoot } from '../../utils';
|
||||
|
||||
const cwd = process.cwd();
|
||||
import { fromRoot } from '../../utils';
|
||||
|
||||
let canCluster;
|
||||
try {
|
||||
|
@ -21,22 +24,17 @@ const pathCollector = function () {
|
|||
};
|
||||
};
|
||||
|
||||
const configPathCollector = pathCollector();
|
||||
const pluginDirCollector = pathCollector();
|
||||
const pluginPathCollector = pathCollector();
|
||||
|
||||
function initServerSettings(opts, extraCliOptions) {
|
||||
const readYamlConfig = require('./read_yaml_config');
|
||||
const settings = readYamlConfig(opts.config);
|
||||
const set = _.partial(_.set, settings);
|
||||
const get = _.partial(_.get, settings);
|
||||
const has = _.partial(_.has, settings);
|
||||
const merge = _.partial(_.merge, settings);
|
||||
|
||||
if (opts.dev) {
|
||||
try { merge(readYamlConfig(fromRoot('config/kibana.dev.yml'))); }
|
||||
catch (e) { null; }
|
||||
}
|
||||
|
||||
if (opts.dev) {
|
||||
set('env', 'development');
|
||||
set('optimize.lazy', true);
|
||||
|
@ -79,8 +77,11 @@ module.exports = function (program) {
|
|||
.option('-e, --elasticsearch <uri>', 'Elasticsearch instance')
|
||||
.option(
|
||||
'-c, --config <path>',
|
||||
'Path to the config file, can be changed with the CONFIG_PATH environment variable as well',
|
||||
process.env.CONFIG_PATH || fromRoot('config/kibana.yml'))
|
||||
'Path to the config file, can be changed with the CONFIG_PATH environment variable as well. ' +
|
||||
'Use mulitple --config args to include multiple config files.',
|
||||
configPathCollector,
|
||||
[ process.env.CONFIG_PATH || fromRoot('config/kibana.yml') ]
|
||||
)
|
||||
.option('-p, --port <port>', 'The port to bind to', parseInt)
|
||||
.option('-q, --quiet', 'Prevent all logging except errors')
|
||||
.option('-Q, --silent', 'Prevent all logging')
|
||||
|
@ -116,6 +117,17 @@ module.exports = function (program) {
|
|||
|
||||
command
|
||||
.action(async function (opts) {
|
||||
if (opts.dev) {
|
||||
try {
|
||||
const kbnDevConfig = fromRoot('config/kibana.dev.yml');
|
||||
if (statSync(kbnDevConfig).isFile()) {
|
||||
opts.config.push(kbnDevConfig);
|
||||
}
|
||||
} catch (err) {
|
||||
// ignore, kibana.dev.yml does not exist
|
||||
}
|
||||
}
|
||||
|
||||
const settings = initServerSettings(opts, this.getUnknownOptions());
|
||||
|
||||
if (canCluster && opts.dev && !isWorker) {
|
||||
|
@ -134,8 +146,11 @@ module.exports = function (program) {
|
|||
catch (err) {
|
||||
const { server } = kbnServer;
|
||||
|
||||
if (server) server.log(['fatal'], err);
|
||||
console.error('FATAL', err);
|
||||
if (err.code === 'EADDRINUSE') {
|
||||
logFatal(`Port ${err.port} is already in use. Another instance of Kibana may be running!`, server);
|
||||
} else {
|
||||
logFatal(err, server);
|
||||
}
|
||||
|
||||
kbnServer.close();
|
||||
process.exit(1); // eslint-disable-line no-process-exit
|
||||
|
@ -144,3 +159,10 @@ module.exports = function (program) {
|
|||
return kbnServer;
|
||||
});
|
||||
};
|
||||
|
||||
function logFatal(message, server) {
|
||||
if (server) {
|
||||
server.log(['fatal'], message);
|
||||
}
|
||||
console.error('FATAL', message);
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import glob from 'glob-all';
|
|||
import rimraf from 'rimraf';
|
||||
import mkdirp from 'mkdirp';
|
||||
import Logger from '../../lib/logger';
|
||||
import { UnsupportedProtocolError } from '../../lib/errors';
|
||||
import { download, _downloadSingle } from '../download';
|
||||
import { join } from 'path';
|
||||
|
||||
|
@ -74,12 +75,12 @@ describe('kibana cli', function () {
|
|||
});
|
||||
});
|
||||
|
||||
it('should throw an ENOTFOUND error for an invalid url', function () {
|
||||
it('should throw an UnsupportedProtocolError for an invalid url', function () {
|
||||
const sourceUrl = 'i am an invalid url';
|
||||
|
||||
return _downloadSingle(settings, logger, sourceUrl)
|
||||
.then(shouldReject, function (err) {
|
||||
expect(err.message).to.match(/ENOTFOUND/);
|
||||
expect(err).to.be.an(UnsupportedProtocolError);
|
||||
expectWorkingPathEmpty();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import downloadHttpFile from './downloaders/http';
|
||||
import downloadLocalFile from './downloaders/file';
|
||||
import { UnsupportedProtocolError } from '../lib/errors';
|
||||
import { parse } from 'url';
|
||||
|
||||
export function _downloadSingle(settings, logger, sourceUrl) {
|
||||
|
@ -8,8 +9,10 @@ export function _downloadSingle(settings, logger, sourceUrl) {
|
|||
|
||||
if (/^file/.test(urlInfo.protocol)) {
|
||||
downloadPromise = downloadLocalFile(logger, decodeURI(urlInfo.path), settings.tempArchiveFile);
|
||||
} else {
|
||||
} else if (/^https?/.test(urlInfo.protocol)) {
|
||||
downloadPromise = downloadHttpFile(logger, sourceUrl, settings.tempArchiveFile, settings.timeout);
|
||||
} else {
|
||||
downloadPromise = Promise.reject(new UnsupportedProtocolError());
|
||||
}
|
||||
|
||||
return downloadPromise;
|
||||
|
@ -29,7 +32,9 @@ export function download(settings, logger) {
|
|||
|
||||
return _downloadSingle(settings, logger, sourceUrl)
|
||||
.catch((err) => {
|
||||
if (err.message === 'ENOTFOUND') {
|
||||
const isUnsupportedProtocol = err instanceof UnsupportedProtocolError;
|
||||
const isDownloadResourceNotFound = err.message === 'ENOTFOUND';
|
||||
if (isUnsupportedProtocol || isDownloadResourceNotFound) {
|
||||
return tryNext();
|
||||
}
|
||||
throw (err);
|
||||
|
|
|
@ -87,8 +87,9 @@ async function mergePackageData(settings, packages) {
|
|||
*/
|
||||
async function extractArchive(settings) {
|
||||
const filter = {
|
||||
paths: [ settings.plugins[0].folder ]
|
||||
paths: [ `kibana/${settings.plugins[0].folder}` ]
|
||||
};
|
||||
|
||||
await extractFiles(settings.tempArchiveFile, settings.workingPath, 2, filter);
|
||||
}
|
||||
|
||||
|
|
1
src/cli_plugin/lib/errors.js
Normal file
1
src/cli_plugin/lib/errors.js
Normal file
|
@ -0,0 +1 @@
|
|||
export class UnsupportedProtocolError extends Error {};
|
54
src/plugins/console/api_server/es_5_0.js
Normal file
54
src/plugins/console/api_server/es_5_0.js
Normal file
|
@ -0,0 +1,54 @@
|
|||
let _ = require("lodash");
|
||||
let Api = require('./api');
|
||||
let parts = [
|
||||
require('./es_5_0/aliases'),
|
||||
require('./es_5_0/aggregations'),
|
||||
require('./es_5_0/cat'),
|
||||
require('./es_5_0/cluster'),
|
||||
require('./es_5_0/count'),
|
||||
require('./es_5_0/document'),
|
||||
require('./es_5_0/field_stats'),
|
||||
require('./es_5_0/filter'),
|
||||
require('./es_5_0/nodes'),
|
||||
require('./es_5_0/globals'),
|
||||
require('./es_5_0/indices'),
|
||||
require('./es_5_0/mappings'),
|
||||
require('./es_5_0/percolator'),
|
||||
require('./es_5_0/query'),
|
||||
require('./es_5_0/snapshot_restore'),
|
||||
require('./es_5_0/search'),
|
||||
require('./es_5_0/settings'),
|
||||
require('./es_5_0/templates')
|
||||
];
|
||||
|
||||
function ES_5_0() {
|
||||
Api.call(this, "es_5_0");
|
||||
_.each(parts, function (apiSection) {
|
||||
apiSection(this);
|
||||
}, this);
|
||||
}
|
||||
|
||||
ES_5_0.prototype = _.create(Api.prototype, {'constructor': ES_5_0});
|
||||
|
||||
(function (cls) {
|
||||
cls.addEndpointDescription = function (endpoint, description) {
|
||||
if (description) {
|
||||
var url_params_def = {};
|
||||
_.each(description.patterns || [], function (p) {
|
||||
if (p.indexOf("{indices}") >= 0) {
|
||||
url_params_def["ignore_unavailable"] = "__flag__";
|
||||
url_params_def["allow_no_indices"] = "__flag__";
|
||||
url_params_def["expand_wildcards"] = ["open", "closed"];
|
||||
}
|
||||
});
|
||||
|
||||
if (url_params_def) {
|
||||
description.url_params = description.url_params || {};
|
||||
_.defaults(description.url_params, url_params_def);
|
||||
}
|
||||
}
|
||||
Object.getPrototypeOf(cls).addEndpointDescription.call(this, endpoint, description);
|
||||
};
|
||||
})(ES_5_0.prototype);
|
||||
|
||||
module.exports = new ES_5_0();
|
436
src/plugins/console/api_server/es_5_0/aggregations.js
Normal file
436
src/plugins/console/api_server/es_5_0/aggregations.js
Normal file
|
@ -0,0 +1,436 @@
|
|||
var simple_metric = {
|
||||
__template: {field: ""},
|
||||
field: "{field}",
|
||||
missing: 0,
|
||||
script: {
|
||||
// populated by a global rule
|
||||
}
|
||||
}, field_metric = {
|
||||
__template: {field: ""},
|
||||
field: "{field}"
|
||||
}, gap_policy = {
|
||||
__one_of: ["skip", "insert_zeros"]
|
||||
}, simple_pipeline = {
|
||||
__template: {
|
||||
buckets_path: ""
|
||||
},
|
||||
buckets_path: "",
|
||||
format: "",
|
||||
gap_policy: gap_policy
|
||||
};
|
||||
var rules = {
|
||||
"*": {
|
||||
"aggs": {
|
||||
__template: {
|
||||
"NAME": {
|
||||
"AGG_TYPE": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"min": simple_metric,
|
||||
"max": simple_metric,
|
||||
"avg": simple_metric,
|
||||
"sum": simple_metric,
|
||||
"stats": simple_metric,
|
||||
"extended_stats": simple_metric,
|
||||
"value_count": {
|
||||
__template: {
|
||||
"field": ""
|
||||
},
|
||||
"field": "{field}",
|
||||
"script": {
|
||||
// populated by a global rule
|
||||
}
|
||||
},
|
||||
"global": {},
|
||||
"filter": {},
|
||||
"filters": {
|
||||
__template: {
|
||||
"filters": {
|
||||
"NAME": {}
|
||||
}
|
||||
},
|
||||
"filters": {
|
||||
"*": {__scope_link: "GLOBAL.filter"}
|
||||
},
|
||||
"other_bucket": {__one_of: [true, false]},
|
||||
"other_bucket_key": ""
|
||||
},
|
||||
"missing": field_metric,
|
||||
"nested": {
|
||||
__template: {
|
||||
"path": ""
|
||||
},
|
||||
"path": ""
|
||||
},
|
||||
"reverse_nested": {
|
||||
__template: {
|
||||
"path": ""
|
||||
},
|
||||
"path": ""
|
||||
},
|
||||
"terms": {
|
||||
__template: {
|
||||
"field": "",
|
||||
"size": 10
|
||||
},
|
||||
"field": "{field}",
|
||||
"size": 10,
|
||||
"shard_size": 10,
|
||||
"order": {
|
||||
__template: {
|
||||
"_term": "asc"
|
||||
},
|
||||
"_term": {__one_of: ["asc", "desc"]},
|
||||
"_count": {__one_of: ["asc", "desc"]},
|
||||
"*": {__one_of: ["asc", "desc"]}
|
||||
},
|
||||
"min_doc_count": 10,
|
||||
"script": {
|
||||
// populated by a global rule
|
||||
},
|
||||
"include": ".*",
|
||||
"exclude": ".*",
|
||||
"execution_hint": {__one_of: ["map", "global_ordinals", "global_ordinals_hash", "global_ordinals_low_cardinality"]},
|
||||
"show_term_doc_count_error": {__one_of: [true, false]},
|
||||
"collect_mode": {__one_of: ["depth_first", "breadth_first"]},
|
||||
"missing": ""
|
||||
},
|
||||
"significant_terms": {
|
||||
__template: {
|
||||
"field": ""
|
||||
},
|
||||
"field": "{field}",
|
||||
"size": 10,
|
||||
"shard_size": 10,
|
||||
"shard_min_doc_count": 10,
|
||||
"min_doc_count": 10,
|
||||
"include": {__one_of: ["*", {pattern: "", flags: ""}]},
|
||||
"exclude": {__one_of: ["*", {pattern: "", flags: ""}]},
|
||||
"execution_hint": {__one_of: ["map", "global_ordinals", "global_ordinals_hash"]},
|
||||
"background_filter": {
|
||||
__scope_link: "GLOBAL.filter"
|
||||
},
|
||||
"mutual_information": {
|
||||
"include_negatives": {__one_of: [true, false]}
|
||||
},
|
||||
"chi_square": {
|
||||
"include_negatives": {__one_of: [true, false]},
|
||||
"background_is_superset": {__one_of: [true, false]}
|
||||
},
|
||||
"percentage": {},
|
||||
"gnd": {
|
||||
"background_is_superset": {__one_of: [true, false]}
|
||||
},
|
||||
"script_heuristic": {
|
||||
__template: {
|
||||
"script": "_subset_freq/(_superset_freq - _subset_freq + 1)"
|
||||
},
|
||||
"script": {
|
||||
// populated by a global rule
|
||||
}
|
||||
}
|
||||
},
|
||||
"range": {
|
||||
__template: {
|
||||
"field": "",
|
||||
"ranges": [
|
||||
{"from": 50, "to": 100},
|
||||
]
|
||||
},
|
||||
"field": "{field}",
|
||||
"ranges": [
|
||||
{"to": 50, "from": 100, "key": ""}
|
||||
],
|
||||
"keyed": {__one_of: [true, false]},
|
||||
"script": {
|
||||
// populated by a global rule
|
||||
}
|
||||
},
|
||||
"date_range": {
|
||||
__template: {
|
||||
"field": "",
|
||||
"ranges": [
|
||||
{"from": "now-10d/d", "to": "now"},
|
||||
]
|
||||
},
|
||||
"field": "{field}",
|
||||
"format": "MM-yyy",
|
||||
"ranges": [
|
||||
{"to": "", "from": "", "key": ""}
|
||||
],
|
||||
"keyed": {__one_of: [true, false]},
|
||||
"script": {
|
||||
// populated by a global rule
|
||||
}
|
||||
},
|
||||
"ip_range": {
|
||||
__template: {
|
||||
"field": "",
|
||||
"ranges": [
|
||||
{"from": "10.0.0.5", "to": "10.0.0.10"},
|
||||
]
|
||||
},
|
||||
"field": "{field}",
|
||||
"format": "MM-yyy",
|
||||
"ranges": [
|
||||
{"to": "", "from": "", "key": "", "mask": "10.0.0.127/25"}
|
||||
],
|
||||
"keyed": {__one_of: [true, false]},
|
||||
"script": {
|
||||
// populated by a global rule
|
||||
}
|
||||
},
|
||||
"histogram": {
|
||||
__template: {
|
||||
"field": "price",
|
||||
"interval": 50
|
||||
},
|
||||
"field": "{field}",
|
||||
"interval": 50,
|
||||
"min_doc_count": 0,
|
||||
"order": {
|
||||
__template: {
|
||||
"_key": "asc"
|
||||
},
|
||||
"_key": {__one_of: ["asc", "desc"]},
|
||||
"_count": {__one_of: ["asc", "desc"]},
|
||||
"*": {__one_of: ["asc", "desc"]}
|
||||
},
|
||||
"keyed": {__one_of: [true, false]},
|
||||
"missing": 0
|
||||
},
|
||||
"date_histogram": {
|
||||
__template: {
|
||||
"field": "date",
|
||||
"interval": "month"
|
||||
},
|
||||
"field": "{field}",
|
||||
"interval": {__one_of: ["year", "quarter", "week", "day", "hour", "minute", "second"]},
|
||||
"min_doc_count": 0,
|
||||
"order": {
|
||||
__template: {
|
||||
"_key": "asc"
|
||||
},
|
||||
"_key": {__one_of: ["asc", "desc"]},
|
||||
"_count": {__one_of: ["asc", "desc"]},
|
||||
"*": {__one_of: ["asc", "desc"]}
|
||||
},
|
||||
"keyed": {__one_of: [true, false]},
|
||||
"pre_zone": "-01:00",
|
||||
"post_zone": "-01:00",
|
||||
"pre_zone_adjust_large_interval": {__one_of: [true, false]},
|
||||
"factor": 1000,
|
||||
"pre_offset": "1d",
|
||||
"post_offset": "1d",
|
||||
"format": "yyyy-MM-dd",
|
||||
"time_zone": "00:00",
|
||||
"missing": ""
|
||||
},
|
||||
"geo_distance": {
|
||||
__template: {
|
||||
"field": "location",
|
||||
"origin": {"lat": 52.3760, "lon": 4.894},
|
||||
"ranges": [
|
||||
{"from": 100, "to": 300},
|
||||
]
|
||||
},
|
||||
"field": "{field}",
|
||||
"origin": {"lat": 0.0, "lon": 0.0},
|
||||
"unit": {__one_of: ["mi", "km", "in", "yd", "m", "cm", "mm"]},
|
||||
"ranges": [
|
||||
{"from": 50, "to": 100}
|
||||
],
|
||||
"distance_type": {__one_of: ["arc", "sloppy_arc", "plane"]}
|
||||
|
||||
},
|
||||
"geohash_grid": {
|
||||
__template: {
|
||||
"field": "",
|
||||
"precision": 3
|
||||
},
|
||||
"field": "{field}",
|
||||
"precision": {__one_of: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]},
|
||||
"size": 10,
|
||||
"shard_size": 10
|
||||
},
|
||||
"percentiles": {
|
||||
__template: {
|
||||
"field": "",
|
||||
"percents": [1.0, 5.0, 25.0, 50.0, 75.0, 95.0, 99.0]
|
||||
},
|
||||
"field": "{field}",
|
||||
"percents": {
|
||||
__template: [1.0, 5.0, 25.0, 50.0, 75.0, 95.0, 99.0],
|
||||
// mark type as list
|
||||
__any_of: []
|
||||
},
|
||||
"script": {
|
||||
// populated by a global rule
|
||||
},
|
||||
"compression": 100,
|
||||
"method": {__one_of: ["hdr", "tdigest"]},
|
||||
missing: 0
|
||||
},
|
||||
"cardinality": {
|
||||
__template: {
|
||||
"field": ""
|
||||
},
|
||||
"precision_threshold": 100,
|
||||
"rehash": true,
|
||||
"script": {
|
||||
// populated by a global rule
|
||||
},
|
||||
missing: ""
|
||||
},
|
||||
"scripted_metric": {
|
||||
__template: {
|
||||
"init_script": "",
|
||||
"map_script": "",
|
||||
"combine_script": "",
|
||||
"reduce_script": ""
|
||||
},
|
||||
"init_script": {
|
||||
__scope_link: "GLOBAL.script"
|
||||
},
|
||||
"map_script": {
|
||||
__scope_link: "GLOBAL.script"
|
||||
},
|
||||
"combine_script": {
|
||||
__scope_link: "GLOBAL.script"
|
||||
},
|
||||
"reduce_script": {
|
||||
__scope_link: "GLOBAL.script"
|
||||
},
|
||||
"lang": "groovy",
|
||||
"params": {},
|
||||
"reduce_params": {}
|
||||
},
|
||||
"geo_bounds": {
|
||||
__template: {
|
||||
field: ""
|
||||
},
|
||||
field: "{field}",
|
||||
wrap_longitude: {__one_of: [true, false]}
|
||||
},
|
||||
"top_hits": {
|
||||
__template: {
|
||||
size: 10
|
||||
},
|
||||
from: 0,
|
||||
size: 10,
|
||||
sort: {
|
||||
__template: [],
|
||||
__scope_link: "_search.sort"
|
||||
},
|
||||
highlight: {},
|
||||
explain: {__one_of: [true, false]},
|
||||
_source: {
|
||||
__template: "",
|
||||
__scope_link: "_search._source"
|
||||
},
|
||||
script_fields: {
|
||||
__scope_link: "_search.script_fields"
|
||||
},
|
||||
fielddata_fields: ["{field}"],
|
||||
version: {__one_of: [true, false]}
|
||||
},
|
||||
"percentile_ranks": {
|
||||
__template: {
|
||||
field: "",
|
||||
values: [10, 15]
|
||||
},
|
||||
field: "{field}",
|
||||
values: [],
|
||||
"script": {
|
||||
// populated by a global rule
|
||||
},
|
||||
"compression": 100,
|
||||
"method": {__one_of: ["hdr", "tdigest"]},
|
||||
missing: 0
|
||||
},
|
||||
"sampler": {
|
||||
__template: {},
|
||||
"field": "{field}",
|
||||
"script": {
|
||||
// populated by a global rule
|
||||
},
|
||||
"shard_size": 100,
|
||||
"max_docs_per_value": 3,
|
||||
"execution_hint": {__one_of: ["map", "global_ordinals", "bytes_hash"]}
|
||||
},
|
||||
"children": {
|
||||
__template: {
|
||||
"type": "",
|
||||
},
|
||||
"type": ""
|
||||
},
|
||||
"derivative": simple_pipeline,
|
||||
"avg_bucket": simple_pipeline,
|
||||
"max_bucket": simple_pipeline,
|
||||
"min_bucket": simple_pipeline,
|
||||
"sum_bucket": simple_pipeline,
|
||||
"moving_avg": {
|
||||
__template: {
|
||||
buckets_path: ""
|
||||
},
|
||||
buckets_path: "",
|
||||
format: "",
|
||||
gap_policy: gap_policy,
|
||||
"window": 5,
|
||||
model: {__one_of: ["simple", "linear", "ewma", "holt", "holt_winters"]},
|
||||
settings: {
|
||||
type: {__one_of: ["add", "mult"]},
|
||||
alpha: 0.5,
|
||||
beta: 0.5,
|
||||
gamma: 0.5,
|
||||
period: 7
|
||||
}
|
||||
},
|
||||
"cumulative_sum": {
|
||||
__template: {
|
||||
buckets_path: ""
|
||||
},
|
||||
buckets_path: "",
|
||||
format: ""
|
||||
},
|
||||
"serial_diff": {
|
||||
__template: {
|
||||
buckets_path: "",
|
||||
lag: 7
|
||||
},
|
||||
lag: 7,
|
||||
gap_policy: gap_policy,
|
||||
buckets_path: "",
|
||||
format: ""
|
||||
},
|
||||
"bucket_script": {
|
||||
__template: {
|
||||
buckets_path: "",
|
||||
script: {}
|
||||
},
|
||||
buckets_path: "",
|
||||
format: "",
|
||||
gap_policy: gap_policy,
|
||||
script: {
|
||||
// populated by a global rule
|
||||
}
|
||||
},
|
||||
"bucket_selector": {
|
||||
__template: {
|
||||
buckets_path: "",
|
||||
script: {}
|
||||
},
|
||||
buckets_path: "",
|
||||
gap_policy: gap_policy,
|
||||
script: {
|
||||
// populated by a global rule
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
module.exports = function (api) {
|
||||
|
||||
api.addGlobalAutocompleteRules('aggregations', rules);
|
||||
api.addGlobalAutocompleteRules('aggs', rules);
|
||||
};
|
71
src/plugins/console/api_server/es_5_0/aliases.js
Normal file
71
src/plugins/console/api_server/es_5_0/aliases.js
Normal file
|
@ -0,0 +1,71 @@
|
|||
module.exports = function (api) {
|
||||
api.addEndpointDescription('_post_aliases', {
|
||||
methods: ['POST'],
|
||||
patterns: [
|
||||
"_aliases",
|
||||
],
|
||||
data_autocomplete_rules: {
|
||||
'actions': {
|
||||
__template: [
|
||||
{'add': {'index': 'test1', 'alias': 'alias1'}}
|
||||
],
|
||||
__any_of: [
|
||||
{
|
||||
add: {
|
||||
index: '{index}',
|
||||
alias: '',
|
||||
filter: {},
|
||||
routing: '1',
|
||||
search_routing: '1,2',
|
||||
index_routing: '1'
|
||||
},
|
||||
remove: {
|
||||
index: '',
|
||||
alias: ''
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
});
|
||||
api.addEndpointDescription('_get_aliases', {
|
||||
methods: ['GET'],
|
||||
patterns: [
|
||||
"_aliases",
|
||||
]
|
||||
});
|
||||
|
||||
var aliasRules = {
|
||||
filter: {},
|
||||
routing: '1',
|
||||
search_routing: '1,2',
|
||||
index_routing: '1'
|
||||
};
|
||||
|
||||
api.addEndpointDescription('_post_alias', {
|
||||
methods: ["POST", "PUT"],
|
||||
patterns: [
|
||||
"{indices}/_alias/{name}"
|
||||
],
|
||||
data_autocomplete_rules: aliasRules
|
||||
});
|
||||
api.addEndpointDescription('_delete_alias', {
|
||||
methods: ["DELETE"],
|
||||
patterns: [
|
||||
"{indices}/_alias/{name}"
|
||||
]
|
||||
});
|
||||
api.addEndpointDescription('_get_alias', {
|
||||
methods: ["GET"],
|
||||
patterns: [
|
||||
"_alias",
|
||||
"{indices}/_alias",
|
||||
"{indices}/_alias/{name}",
|
||||
"_alias/{name}"
|
||||
]
|
||||
});
|
||||
|
||||
api.addGlobalAutocompleteRules('aliases', {
|
||||
'*': aliasRules
|
||||
});
|
||||
};
|
56
src/plugins/console/api_server/es_5_0/cat.js
Normal file
56
src/plugins/console/api_server/es_5_0/cat.js
Normal file
|
@ -0,0 +1,56 @@
|
|||
let _ = require("lodash");
|
||||
|
||||
function addSimpleCat(endpoint, api, params, patterns) {
|
||||
var url_params = {"help": "__flag__", "v": "__flag__", "bytes": ["b"]};
|
||||
_.each(params || [], function (p) {
|
||||
if (_.isString(p)) {
|
||||
url_params[p] = "__flag__";
|
||||
}
|
||||
else {
|
||||
var k = Object.keys(p)[0];
|
||||
url_params[k] = p[k];
|
||||
}
|
||||
});
|
||||
api.addEndpointDescription(endpoint, {
|
||||
match: endpoint,
|
||||
url_params: url_params,
|
||||
patterns: patterns || [endpoint]
|
||||
});
|
||||
}
|
||||
|
||||
function addNodeattrsCat(api) {
|
||||
api.addEndpointDescription('_cat/nodeattrs', {
|
||||
methods: ['GET'],
|
||||
patterns: [
|
||||
"_cat/nodeattrs"
|
||||
],
|
||||
url_params: {
|
||||
help: "__flag__",
|
||||
v: "__flag__",
|
||||
h: ["node", "name", "id", "nodeId", "pid", "p", "host", "h", "ip", "i", "port", "po", "attr", "attr.name", "value", "attr.value"]
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = function (api) {
|
||||
addSimpleCat('_cat/aliases', api);
|
||||
addSimpleCat('_cat/allocation', api, null, ['_cat/allocation', '_cat/allocation/{nodes}']);
|
||||
addSimpleCat('_cat/count', api);
|
||||
addSimpleCat('_cat/health', api, [
|
||||
{"ts": ["false", "true"]}
|
||||
]);
|
||||
addSimpleCat('_cat/indices', api, [
|
||||
{h: []},
|
||||
"pri",
|
||||
],
|
||||
['_cat/indices', '_cat/indices/{indices}']);
|
||||
addSimpleCat('_cat/master', api);
|
||||
addSimpleCat('_cat/nodes', api);
|
||||
addSimpleCat('_cat/pending_tasks', api);
|
||||
addSimpleCat('_cat/recovery', api);
|
||||
addSimpleCat('_cat/thread_pool', api);
|
||||
addSimpleCat('_cat/shards', api);
|
||||
addSimpleCat('_cat/plugins', api);
|
||||
addSimpleCat('_cat/segments', api);
|
||||
addNodeattrsCat(api);
|
||||
};
|
142
src/plugins/console/api_server/es_5_0/cluster.js
Normal file
142
src/plugins/console/api_server/es_5_0/cluster.js
Normal file
|
@ -0,0 +1,142 @@
|
|||
module.exports = function (api) {
|
||||
api.addEndpointDescription('_cluster/nodes/stats');
|
||||
api.addEndpointDescription('_cluster/state', {
|
||||
patterns: [
|
||||
"_cluster/state",
|
||||
"_cluster/state/{metrics}",
|
||||
"_cluster/state/{metrics}/{indices}"
|
||||
],
|
||||
url_components: {
|
||||
"metrics": ["version", "master_node", "nodes", "routing_table", "routing_node", "metadata", "blocks"]
|
||||
}
|
||||
});
|
||||
api.addEndpointDescription('_cluster/health', {
|
||||
url_params: {
|
||||
"local": "__flag__",
|
||||
"level": ["indices", "shards"],
|
||||
"master_timeout": "30s",
|
||||
"timeout": "30s",
|
||||
"wait_for_status": ["yellow", "green"],
|
||||
"wait_for_relocating_shards": 0,
|
||||
"wait_for_active_shards": 0,
|
||||
"wait_for_nodes": 0
|
||||
}
|
||||
});
|
||||
api.addEndpointDescription('_cluster/pending_tasks');
|
||||
api.addEndpointDescription('get_cluster/settings', {
|
||||
patterns: [
|
||||
'_cluster/settings'
|
||||
]
|
||||
});
|
||||
|
||||
api.addEndpointDescription('put_cluster/settings', {
|
||||
methods: ['PUT'],
|
||||
patterns: [
|
||||
'_cluster/settings'
|
||||
],
|
||||
data_autocomplete_rules: {
|
||||
persistent: {
|
||||
cluster: {
|
||||
routing: {
|
||||
'allocation.enable': {__one_of: ["all", "primaries", "new_primaries", "none"]},
|
||||
'allocation.disk.threshold_enabled': {__one_of: [false, true]},
|
||||
'allocation.disk.watermark.low': '85%',
|
||||
'allocation.disk.watermark.high': '90%',
|
||||
'allocation.disk.include_relocations': {__one_of: [true, false]},
|
||||
'allocation.disk.reroute_interval': '60s',
|
||||
'allocation.exclude': {
|
||||
'_ip': "",
|
||||
'_name': "",
|
||||
'_host': "",
|
||||
'_id': ""
|
||||
},
|
||||
'allocation.include': {
|
||||
'_ip': "",
|
||||
'_name': "",
|
||||
'_host': "",
|
||||
'_id': ""
|
||||
},
|
||||
'allocation.require': {
|
||||
'_ip': "",
|
||||
'_name': "",
|
||||
'_host': "",
|
||||
'_id': ""
|
||||
},
|
||||
'allocation.awareness.attributes': [],
|
||||
'allocation.awareness.force': {
|
||||
'*': {
|
||||
'values': []
|
||||
}
|
||||
},
|
||||
'allocation.allow_rebalance': {__one_of: ['always', 'indices_primaries_active', 'indices_all_active']},
|
||||
'allocation.cluster_concurrent_rebalance': 2,
|
||||
'allocation.node_initial_primaries_recoveries': 4,
|
||||
'allocation.node_concurrent_recoveries': 2,
|
||||
'allocation.same_shard.host': {__one_of: [false, true]}
|
||||
}
|
||||
},
|
||||
indices: {
|
||||
breaker: {
|
||||
"total.limit": "70%",
|
||||
"fielddata.limit": "60%",
|
||||
"fielddata.overhead": 1.03,
|
||||
"request.limit": "40%",
|
||||
"request.overhead": 1.0
|
||||
}
|
||||
}
|
||||
},
|
||||
transient: {
|
||||
__scope_link: '.persistent'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
api.addEndpointDescription('_cluster/reroute', {
|
||||
methods: ['POST'],
|
||||
url_params: {
|
||||
explain: "__flag__",
|
||||
dry_run: "__flag__"
|
||||
},
|
||||
data_autocomplete_rules: {
|
||||
commands: [
|
||||
{
|
||||
move: {
|
||||
__template: {
|
||||
index: "",
|
||||
shard: 0,
|
||||
from_node: "",
|
||||
to_node: ""
|
||||
},
|
||||
index: "{index}",
|
||||
shard: 0,
|
||||
from_node: "{node}",
|
||||
to_node: "{node}"
|
||||
},
|
||||
cancel: {
|
||||
__template: {
|
||||
index: "",
|
||||
shard: 0,
|
||||
node: ""
|
||||
},
|
||||
index: "{index}",
|
||||
shard: 0,
|
||||
node: "{node}",
|
||||
allow_primary: {__one_of: [true, false]}
|
||||
},
|
||||
allocate: {
|
||||
__template: {
|
||||
index: "",
|
||||
shard: 0,
|
||||
node: ""
|
||||
},
|
||||
index: "{index}",
|
||||
shard: 0,
|
||||
node: "{node}",
|
||||
allow_primary: {__one_of: [true, false]}
|
||||
}
|
||||
}
|
||||
],
|
||||
dry_run: {__one_of: [true, false]}
|
||||
}
|
||||
});
|
||||
};
|
22
src/plugins/console/api_server/es_5_0/count.js
Normal file
22
src/plugins/console/api_server/es_5_0/count.js
Normal file
|
@ -0,0 +1,22 @@
|
|||
module.exports = function (api) {
|
||||
api.addEndpointDescription('_count', {
|
||||
methods: ['GET', 'POST'],
|
||||
priority: 10, // collides with get doc by id
|
||||
patterns: [
|
||||
"{indices}/{types}/_count",
|
||||
"{indices}/_count",
|
||||
"_count"
|
||||
],
|
||||
url_params: {
|
||||
preference: ["_primary", "_primary_first", "_local", "_only_node:xyz", "_prefer_node:xyz", "_shards:2,3"],
|
||||
routing: "",
|
||||
min_score: 1.0,
|
||||
terminate_after: 10,
|
||||
},
|
||||
data_autocomplete_rules: {
|
||||
query: {
|
||||
// populated by a global rule
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
233
src/plugins/console/api_server/es_5_0/document.js
Normal file
233
src/plugins/console/api_server/es_5_0/document.js
Normal file
|
@ -0,0 +1,233 @@
|
|||
module.exports = function (api) {
|
||||
api.addEndpointDescription('_get_doc', {
|
||||
methods: ['GET'],
|
||||
patterns: [
|
||||
"{index}/{type}/{id}"
|
||||
],
|
||||
url_params: {
|
||||
"version": 1,
|
||||
"routing": "",
|
||||
"parent": "",
|
||||
"_source": "",
|
||||
"_source_exclude": "",
|
||||
"_source_include": ""
|
||||
}
|
||||
});
|
||||
api.addEndpointDescription('_get_doc_source', {
|
||||
methods: ['GET'],
|
||||
patterns: [
|
||||
"{index}/{type}/{id}/_source"
|
||||
],
|
||||
url_params: {
|
||||
"version": 1,
|
||||
"routing": "",
|
||||
"parent": "",
|
||||
"_source_exclude": "",
|
||||
"_source_include": ""
|
||||
}
|
||||
});
|
||||
api.addEndpointDescription('_delete_doc', {
|
||||
methods: ['DELETE'],
|
||||
patterns: [
|
||||
"{index}/{type}/{id}"
|
||||
],
|
||||
url_params: {
|
||||
"version": 1,
|
||||
"version_type": ["external", "internal"],
|
||||
"routing": "",
|
||||
"parent": ""
|
||||
}
|
||||
});
|
||||
api.addEndpointDescription('index_doc', {
|
||||
methods: ['PUT', 'POST'],
|
||||
patterns: [
|
||||
"{index}/{type}/{id}"
|
||||
],
|
||||
url_params: {
|
||||
"version": 1,
|
||||
"version_type": ["external", "internal"],
|
||||
"op_type": ["create"],
|
||||
"routing": "",
|
||||
"parent": "",
|
||||
"timestamp": "",
|
||||
"ttl": "5m",
|
||||
"consistency": ["qurom", "one", "all"],
|
||||
"refresh": "__flag__",
|
||||
"timeout": "1m"
|
||||
}
|
||||
});
|
||||
api.addEndpointDescription('create_doc', {
|
||||
methods: ['PUT', 'POST'],
|
||||
patterns: [
|
||||
"{index}/{type}/{id}/_create"
|
||||
],
|
||||
url_params: {
|
||||
"version": 1,
|
||||
"version_type": ["external", "internal"],
|
||||
"routing": "",
|
||||
"parent": "",
|
||||
"timestamp": "",
|
||||
"ttl": "5m",
|
||||
"consistency": ["qurom", "one", "all"],
|
||||
"refresh": "__flag__",
|
||||
"timeout": "1m"
|
||||
}
|
||||
});
|
||||
api.addEndpointDescription('index_doc_no_id', {
|
||||
methods: ['POST'],
|
||||
patterns: [
|
||||
"{index}/{type}"
|
||||
],
|
||||
url_params: {
|
||||
"version": 1,
|
||||
"version_type": ["external", "internal"],
|
||||
"routing": "",
|
||||
"parent": "",
|
||||
"timestamp": "",
|
||||
"ttl": "5m",
|
||||
"consistency": ["qurom", "one", "all"],
|
||||
"refresh": "__flag__",
|
||||
"timeout": "1m"
|
||||
}
|
||||
});
|
||||
|
||||
api.addEndpointDescription('_update', {
|
||||
methods: ['POST'],
|
||||
patterns: [
|
||||
"{index}/{type}/{id}/_update"
|
||||
],
|
||||
url_params: {
|
||||
"version": 1,
|
||||
"version_type": ["force", "internal"],
|
||||
"routing": "",
|
||||
"parent": "",
|
||||
"timestamp": "",
|
||||
"consistency": ["qurom", "one", "all"],
|
||||
"refresh": "__flag__",
|
||||
"timeout": "1m",
|
||||
"retry_on_conflict": 3,
|
||||
"fields": ""
|
||||
},
|
||||
data_autocomplete_rules: {
|
||||
"script": {
|
||||
// populated by a global rule
|
||||
},
|
||||
"doc": {},
|
||||
"upsert": {},
|
||||
"scripted_upsert": {__one_of: [true, false]}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
api.addEndpointDescription('_put_script', {
|
||||
methods: ['POST', 'PUT'],
|
||||
patterns: [
|
||||
"_scripts/{lang}/{id}",
|
||||
"_scripts/{lang}/{id}/_create"
|
||||
],
|
||||
url_components: {
|
||||
"lang": [
|
||||
"groovy",
|
||||
"expressions"
|
||||
]
|
||||
},
|
||||
data_autocomplete_rules: {
|
||||
"script": ""
|
||||
}
|
||||
});
|
||||
|
||||
api.addEndpointDescription('_termvectors', {
|
||||
methods: ['GET', 'POST'],
|
||||
patterns: [
|
||||
"{index}/{type}/_termvectors"
|
||||
],
|
||||
priority: 10, // collision with get doc
|
||||
url_params: {
|
||||
"fields": "",
|
||||
"offsets": "__flag__",
|
||||
"payloads": "__flag__",
|
||||
"positions": "__flag__",
|
||||
"term_statistics": "__flag__",
|
||||
"field_statistics": "__flag__",
|
||||
"routing": "",
|
||||
"version": 1,
|
||||
"version_type": ["external", "external_gt", "external_gte", "force", "internal"],
|
||||
"parent": "",
|
||||
"preference": ""
|
||||
},
|
||||
data_autocomplete_rules: {
|
||||
fields: [
|
||||
"{field}"
|
||||
],
|
||||
offsets: {__one_of: [false, true]},
|
||||
payloads: {__one_of: [false, true]},
|
||||
positions: {__one_of: [false, true]},
|
||||
term_statistics: {__one_of: [true, false]},
|
||||
field_statistics: {__one_of: [false, true]},
|
||||
per_field_analyzer: {
|
||||
__template: {"FIELD": ""},
|
||||
"{field}": ""
|
||||
},
|
||||
routing: "",
|
||||
version: 1,
|
||||
version_type: ["external", "external_gt", "external_gte", "force", "internal"],
|
||||
doc: {},
|
||||
filter: { // TODO: Exclude from global filter rules
|
||||
"max_num_terms": 1,
|
||||
"min_term_freq": 1,
|
||||
"max_term_freq": 1,
|
||||
"min_doc_freq": 1,
|
||||
"max_doc_freq": 1,
|
||||
"min_word_length": 1,
|
||||
"max_word_length": 1
|
||||
}
|
||||
}
|
||||
});
|
||||
api.addEndpointDescription('_termvectors_id', {
|
||||
methods: ['GET', 'POST'],
|
||||
patterns: [
|
||||
"{index}/{type}/{id}/_termvectors"
|
||||
],
|
||||
url_params: {
|
||||
"fields": "",
|
||||
"offsets": "__flag__",
|
||||
"payloads": "__flag__",
|
||||
"positions": "__flag__",
|
||||
"term_statistics": "__flag__",
|
||||
"field_statistics": "__flag__",
|
||||
"routing": "",
|
||||
"version": 1,
|
||||
"version_type": ["external", "external_gt", "external_gte", "force", "internal"],
|
||||
"parent": "",
|
||||
"preference": "",
|
||||
"dfs": "__flag__"
|
||||
},
|
||||
data_autocomplete_rules: {
|
||||
fields: [
|
||||
"{field}"
|
||||
],
|
||||
offsets: {__one_of: [false, true]},
|
||||
payloads: {__one_of: [false, true]},
|
||||
positions: {__one_of: [false, true]},
|
||||
term_statistics: {__one_of: [true, false]},
|
||||
field_statistics: {__one_of: [false, true]},
|
||||
dfs: {__one_of: [true, false]},
|
||||
per_field_analyzer: {
|
||||
__template: {"FIELD": ""},
|
||||
"{field}": ""
|
||||
},
|
||||
routing: "",
|
||||
version: 1,
|
||||
version_type: ["external", "external_gt", "external_gte", "force", "internal"],
|
||||
filter: { // TODO: Exclude from global filter rules
|
||||
"max_num_terms": 1,
|
||||
"min_term_freq": 1,
|
||||
"max_term_freq": 1,
|
||||
"min_doc_freq": 1,
|
||||
"max_doc_freq": 1,
|
||||
"min_word_length": 1,
|
||||
"max_word_length": 1
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
47
src/plugins/console/api_server/es_5_0/field_stats.js
Normal file
47
src/plugins/console/api_server/es_5_0/field_stats.js
Normal file
|
@ -0,0 +1,47 @@
|
|||
module.exports = function (api) {
|
||||
api.addEndpointDescription('_field_stats', {
|
||||
methods: ['GET', 'POST'],
|
||||
patterns: [
|
||||
"_field_stats",
|
||||
"{indices}/_field_stats"
|
||||
],
|
||||
url_params: {
|
||||
fields: [],
|
||||
level: ["cluster", "indices"],
|
||||
ignore_unavailable: ["true", "false"],
|
||||
allow_no_indices: [false, true],
|
||||
expand_wildcards: ["open", "closed", "none", "all"]
|
||||
},
|
||||
data_autocomplete_rules: {
|
||||
fields: [
|
||||
"{field}",
|
||||
],
|
||||
index_constraints: {
|
||||
"{field}": {
|
||||
min_value: {
|
||||
gt: "MIN",
|
||||
gte: "MAX",
|
||||
lt: "MIN",
|
||||
lte: "MAX"
|
||||
},
|
||||
max_value: {
|
||||
gt: "MIN",
|
||||
gte: "MAX",
|
||||
lt: "MIN",
|
||||
lte: "MAX"
|
||||
}
|
||||
},
|
||||
__template: {
|
||||
"FIELD": {
|
||||
min_value: {
|
||||
gt: "MIN"
|
||||
},
|
||||
max_value: {
|
||||
lt: "MAX"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
336
src/plugins/console/api_server/es_5_0/filter.js
Normal file
336
src/plugins/console/api_server/es_5_0/filter.js
Normal file
|
@ -0,0 +1,336 @@
|
|||
var filters = {};
|
||||
|
||||
filters.and = {
|
||||
__template: {
|
||||
filters: [
|
||||
{}
|
||||
]
|
||||
},
|
||||
filters: [
|
||||
{
|
||||
__scope_link: '.'
|
||||
}
|
||||
],
|
||||
};
|
||||
|
||||
|
||||
filters.bool = {
|
||||
__scope_link: 'GLOBAL.query'
|
||||
};
|
||||
|
||||
|
||||
filters.exists = {
|
||||
__template: {
|
||||
'field': 'FIELD_NAME'
|
||||
},
|
||||
'field': '{field}'
|
||||
};
|
||||
|
||||
|
||||
filters.ids = {
|
||||
__template: {
|
||||
'values': ['ID']
|
||||
},
|
||||
'type': '{type}',
|
||||
'values': ['']
|
||||
};
|
||||
|
||||
|
||||
filters.limit = {
|
||||
__template: {
|
||||
value: 100
|
||||
},
|
||||
value: 100
|
||||
};
|
||||
|
||||
|
||||
filters.type = {
|
||||
__template: {
|
||||
value: 'TYPE'
|
||||
},
|
||||
value: '{type}'
|
||||
};
|
||||
|
||||
|
||||
filters.geo_bounding_box = {
|
||||
__template: {
|
||||
'FIELD': {
|
||||
'top_left': {
|
||||
'lat': 40.73,
|
||||
'lon': -74.1
|
||||
},
|
||||
'bottom_right': {
|
||||
'lat': 40.717,
|
||||
'lon': -73.99
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
'{field}': {
|
||||
top_left: {
|
||||
lat: 40.73,
|
||||
lon: -74.1
|
||||
},
|
||||
bottom_right: {
|
||||
lat: 40.73,
|
||||
lon: -74.1
|
||||
}
|
||||
},
|
||||
type: {
|
||||
__one_of: ['memory', 'indexed']
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
filters.geo_distance = {
|
||||
__template: {
|
||||
distance: 100,
|
||||
distance_unit: 'km',
|
||||
'FIELD': {
|
||||
lat: 40.73,
|
||||
lon: -74.1
|
||||
}
|
||||
},
|
||||
distance: 100,
|
||||
distance_unit: {
|
||||
__one_of: ['km', 'miles']
|
||||
},
|
||||
distance_type: {
|
||||
__one_of: ['arc', 'plane']
|
||||
},
|
||||
optimize_bbox: {
|
||||
__one_of: ['memory', 'indexed', 'none']
|
||||
},
|
||||
'{field}': {
|
||||
lat: 40.73,
|
||||
lon: -74.1
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
filters.geo_distance_range = {
|
||||
__template: {
|
||||
from: 100,
|
||||
to: 200,
|
||||
distance_unit: 'km',
|
||||
'FIELD': {
|
||||
lat: 40.73,
|
||||
lon: -74.1
|
||||
}
|
||||
},
|
||||
from: 100,
|
||||
to: 200,
|
||||
|
||||
distance_unit: {
|
||||
__one_of: ['km', 'miles']
|
||||
},
|
||||
distance_type: {
|
||||
__one_of: ['arc', 'plane']
|
||||
},
|
||||
include_lower: {
|
||||
__one_of: [true, false]
|
||||
},
|
||||
include_upper: {
|
||||
__one_of: [true, false]
|
||||
},
|
||||
|
||||
'{field}': {
|
||||
lat: 40.73,
|
||||
lon: -74.1
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
filters.geo_polygon = {
|
||||
__template: {
|
||||
'FIELD': {
|
||||
'points': [
|
||||
{
|
||||
lat: 40.73,
|
||||
lon: -74.1
|
||||
},
|
||||
{
|
||||
lat: 40.83,
|
||||
lon: -75.1
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
'{field}': {
|
||||
points: [
|
||||
{
|
||||
lat: 40.73,
|
||||
lon: -74.1
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
filters.geo_shape = {
|
||||
__template: {
|
||||
'FIELD': {
|
||||
shape: {
|
||||
type: 'envelope',
|
||||
coordinates: [
|
||||
[-45, 45],
|
||||
[45, -45]
|
||||
]
|
||||
},
|
||||
'relation': 'within'
|
||||
}
|
||||
},
|
||||
'{field}': {
|
||||
shape: {
|
||||
type: '',
|
||||
coordinates: []
|
||||
},
|
||||
indexed_shape: {
|
||||
id: '',
|
||||
index: '{index}',
|
||||
type: '{type}',
|
||||
shape_field_name: 'shape'
|
||||
},
|
||||
relation: {
|
||||
__one_of: ['within', 'intersects', 'disjoint']
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
filters.has_child = {
|
||||
__template: {
|
||||
type: 'TYPE',
|
||||
filter: {}
|
||||
},
|
||||
type: '{type}',
|
||||
query: {},
|
||||
filter: {},
|
||||
_scope: '',
|
||||
min_children: 1,
|
||||
max_children: 10
|
||||
};
|
||||
|
||||
|
||||
filters.has_parent = {
|
||||
__template: {
|
||||
parent_type: 'TYPE',
|
||||
filter: {}
|
||||
},
|
||||
parent_type: '{type}',
|
||||
query: {},
|
||||
filter: {},
|
||||
_scope: ''
|
||||
};
|
||||
|
||||
|
||||
filters.m = filters.missing = {
|
||||
__template: {
|
||||
field: 'FIELD'
|
||||
},
|
||||
existence: {
|
||||
__one_of: [true, false]
|
||||
},
|
||||
null_value: {
|
||||
__one_of: [true, false]
|
||||
},
|
||||
field: '{field}'
|
||||
};
|
||||
|
||||
|
||||
filters.not = {
|
||||
__template: {
|
||||
filter: {}
|
||||
},
|
||||
filter: {}
|
||||
};
|
||||
|
||||
|
||||
filters.range = {
|
||||
__template: {
|
||||
'FIELD': {
|
||||
gte: 10,
|
||||
lte: 20
|
||||
}
|
||||
},
|
||||
"{field}": {
|
||||
gte: 1,
|
||||
gt: 1,
|
||||
lte: 20,
|
||||
lt: 20,
|
||||
time_zone: "+1:00",
|
||||
"format": "dd/MM/yyyy||yyyy",
|
||||
execution: {__one_of: ["index", "fielddata"]}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
filters.or = {
|
||||
__template: {
|
||||
filters: [
|
||||
{}
|
||||
]
|
||||
},
|
||||
filters: [
|
||||
{
|
||||
__scope_link: '.'
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
filters.prefix = {
|
||||
__template: {
|
||||
'FIELD': 'VALUE'
|
||||
},
|
||||
'{field}': ''
|
||||
};
|
||||
|
||||
|
||||
filters.query = {
|
||||
// global query
|
||||
};
|
||||
|
||||
filters.script = {
|
||||
__template: {
|
||||
script: {}
|
||||
},
|
||||
script: {
|
||||
// populated by a global rule
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
filters.term = {
|
||||
__template: {
|
||||
'FIELD': 'VALUE'
|
||||
},
|
||||
'{field}': ''
|
||||
};
|
||||
|
||||
|
||||
filters.terms = {
|
||||
__template: {
|
||||
'FIELD': ['VALUE1', 'VALUE2']
|
||||
},
|
||||
field: ['{field}'],
|
||||
execution: {
|
||||
__one_of: ['plain', 'bool', 'and', 'or', 'bool_nocache', 'and_nocache', 'or_nocache']
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
filters.nested = {
|
||||
__template: {
|
||||
path: 'path_to_nested_doc',
|
||||
query: {}
|
||||
},
|
||||
query: {},
|
||||
path: '',
|
||||
_name: ''
|
||||
};
|
||||
|
||||
module.exports = function (api) {
|
||||
api.addGlobalAutocompleteRules('filter', filters);
|
||||
};
|
||||
|
24
src/plugins/console/api_server/es_5_0/globals.js
Normal file
24
src/plugins/console/api_server/es_5_0/globals.js
Normal file
|
@ -0,0 +1,24 @@
|
|||
module.exports = function (api) {
|
||||
api.addGlobalAutocompleteRules('highlight', {
|
||||
pre_tags: {},
|
||||
post_tags: {},
|
||||
tags_schema: {},
|
||||
fields: {
|
||||
'{field}': {
|
||||
fragment_size: 20,
|
||||
number_of_fragments: 3
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
api.addGlobalAutocompleteRules('script', {
|
||||
__template: {
|
||||
inline: "SCRIPT"
|
||||
},
|
||||
inline: "SCRIPT",
|
||||
file: "FILE_SCRIPT_NAME",
|
||||
id: "SCRIPT_ID",
|
||||
lang: "",
|
||||
params: {}
|
||||
});
|
||||
};
|
208
src/plugins/console/api_server/es_5_0/indices.js
Normal file
208
src/plugins/console/api_server/es_5_0/indices.js
Normal file
|
@ -0,0 +1,208 @@
|
|||
module.exports = function (api) {
|
||||
api.addEndpointDescription('_refresh', {
|
||||
methods: ['POST'],
|
||||
patterns: [
|
||||
"_refresh",
|
||||
"{indices}/_refresh"
|
||||
],
|
||||
});
|
||||
|
||||
api.addEndpointDescription('_flush', {
|
||||
methods: ['POST'],
|
||||
patterns: [
|
||||
"_flush",
|
||||
"{indices}/_flush"
|
||||
],
|
||||
url_params: {
|
||||
wait_if_ongoing: [true, false],
|
||||
force: [true, false]
|
||||
}
|
||||
});
|
||||
|
||||
api.addEndpointDescription('_flush_synced', {
|
||||
methods: ['POST'],
|
||||
patterns: [
|
||||
"_flush/synced",
|
||||
"{indices}/_flush/synced"
|
||||
]
|
||||
});
|
||||
|
||||
api.addEndpointDescription('_stats', {
|
||||
patterns: [
|
||||
"_stats",
|
||||
"_stats/{metrics}",
|
||||
"{indices}/_stats",
|
||||
"{indices}/_stats/{metrics}",
|
||||
],
|
||||
url_components: {
|
||||
"metrics": [
|
||||
"docs",
|
||||
"store",
|
||||
"indexing",
|
||||
"search",
|
||||
"get",
|
||||
"merge",
|
||||
"refresh",
|
||||
"flush",
|
||||
"warmer",
|
||||
"filter_cache",
|
||||
"percolate",
|
||||
"segments",
|
||||
"fielddata",
|
||||
"completion",
|
||||
"translog",
|
||||
"query_cache",
|
||||
"commit",
|
||||
"_all"
|
||||
]
|
||||
},
|
||||
url_params: {
|
||||
"fields": [],
|
||||
"types": [],
|
||||
"completion_fields": [],
|
||||
"fielddata_fields": [],
|
||||
"level": ["cluster", "indices", "shards"]
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
api.addEndpointDescription('_segments', {
|
||||
patterns: [
|
||||
"{indices}/_segments",
|
||||
"_segments"
|
||||
]
|
||||
});
|
||||
|
||||
api.addEndpointDescription('_recovery', {
|
||||
patterns: [
|
||||
"{indices}/_recovery",
|
||||
"_recovery"
|
||||
],
|
||||
url_params: {
|
||||
detailed: "__flag__",
|
||||
active_only: "__flag__",
|
||||
human: "__flag__"
|
||||
}
|
||||
});
|
||||
|
||||
api.addEndpointDescription('_analyze', {
|
||||
methods: ['GET', 'POST'],
|
||||
patterns: [
|
||||
"{indices}/_analyze",
|
||||
"_analyze"
|
||||
],
|
||||
url_params: {
|
||||
"analyzer": "",
|
||||
"char_filters": [],
|
||||
"field": "",
|
||||
"filters": [],
|
||||
"text": "",
|
||||
"tokenizer": ""
|
||||
}
|
||||
});
|
||||
|
||||
api.addEndpointDescription('_validate_query', {
|
||||
methods: ['GET', 'POST'],
|
||||
patterns: [
|
||||
"{indices}/_validate/query",
|
||||
"_validate/query"
|
||||
],
|
||||
url_params: {
|
||||
explain: "__flag__",
|
||||
rewrite: "__flag__"
|
||||
},
|
||||
data_autocomplete_rules: {
|
||||
query: {
|
||||
// populated by a global rule
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
api.addEndpointDescription('_shard_stores', {
|
||||
methods: ['GET'],
|
||||
patterns: [
|
||||
"{indices}/_shard_stores",
|
||||
"_shard_stores"
|
||||
],
|
||||
url_params: {
|
||||
status: ["green", "yellow", "red", "all"]
|
||||
}
|
||||
});
|
||||
|
||||
api.addEndpointDescription('__create_index__', {
|
||||
methods: ['PUT'],
|
||||
patterns: [
|
||||
"{index}"
|
||||
],
|
||||
data_autocomplete_rules: {
|
||||
mappings: {
|
||||
__scope_link: '_put_mapping'
|
||||
},
|
||||
settings: {
|
||||
__scope_link: '_put_settings'
|
||||
},
|
||||
aliases: {
|
||||
__template: {
|
||||
"NAME": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
api.addEndpointDescription('__delete_indices__', {
|
||||
methods: ['DELETE'],
|
||||
patterns: [
|
||||
"{indices}"
|
||||
]
|
||||
});
|
||||
|
||||
api.addEndpointDescription('_get_index_settings', {
|
||||
methods: ['GET',],
|
||||
patterns: [
|
||||
"{indices}/_settings",
|
||||
],
|
||||
url_params: {
|
||||
flat_settings: "__flag__"
|
||||
}
|
||||
});
|
||||
|
||||
api.addEndpointDescription('_get_index', {
|
||||
methods: ['GET',],
|
||||
patterns: [
|
||||
"{indices}",
|
||||
"{indices}/{feature}"
|
||||
],
|
||||
url_components: {
|
||||
"feature": [
|
||||
"_mappings",
|
||||
"_aliases"
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
api.addEndpointDescription('_cache/clear', {
|
||||
patterns: [
|
||||
"_cache/clear",
|
||||
"{indices}/_cache/clear"
|
||||
]
|
||||
});
|
||||
|
||||
api.addEndpointDescription('_upgrade', {
|
||||
methods: ["POST"],
|
||||
patterns: [
|
||||
"_upgrade",
|
||||
"{indices}/_upgrade"
|
||||
],
|
||||
url_params: {
|
||||
wait_for_completion: "__flag__"
|
||||
}
|
||||
});
|
||||
|
||||
api.addEndpointDescription('_upgrade_status', {
|
||||
methods: ["GET"],
|
||||
patterns: [
|
||||
"_upgrade",
|
||||
"{indices}/_upgrade"
|
||||
]
|
||||
});
|
||||
};
|
218
src/plugins/console/api_server/es_5_0/mappings.js
Normal file
218
src/plugins/console/api_server/es_5_0/mappings.js
Normal file
|
@ -0,0 +1,218 @@
|
|||
let _ = require("lodash");
|
||||
|
||||
var BOOLEAN = {
|
||||
__one_of: [true, false]
|
||||
};
|
||||
|
||||
module.exports = function (api) {
|
||||
api.addEndpointDescription('_get_mapping', {
|
||||
methods: ['GET'],
|
||||
priority: 10, // collides with get doc by id
|
||||
patterns: [
|
||||
"{indices}/_mapping",
|
||||
"{indices}/_mapping/{types}",
|
||||
"{indices}/{types}/_mapping",
|
||||
"_mapping"
|
||||
]
|
||||
});
|
||||
api.addEndpointDescription('_get_field_mapping', {
|
||||
methods: ['GET'],
|
||||
priority: 10, // collides with get doc by id
|
||||
patterns: [
|
||||
"{indices}/_mapping/field/{fields}",
|
||||
"{indices}/_mapping/{type}/field/{fields}"
|
||||
],
|
||||
url_params: {
|
||||
"include_defaults": "__flag__"
|
||||
}
|
||||
});
|
||||
api.addEndpointDescription('_delete_mapping', {
|
||||
methods: ['DELETE'],
|
||||
priority: 10, // collides with get doc by id
|
||||
patterns: [
|
||||
"{indices}/_mapping",
|
||||
"{indices}/_mapping/{types}",
|
||||
"{indices}/{types}/_mapping",
|
||||
"_mapping"
|
||||
]
|
||||
});
|
||||
api.addEndpointDescription('_put_type_mapping', {
|
||||
methods: ['PUT', 'POST'],
|
||||
patterns: [
|
||||
"{indices}/{type}/_mapping",
|
||||
"{indices}/_mapping/{type}"
|
||||
],
|
||||
priority: 10, // collides with put doc by id
|
||||
data_autocomplete_rules: {
|
||||
__template: {
|
||||
properties: {
|
||||
'FIELD': {}
|
||||
}
|
||||
},
|
||||
'_source': {
|
||||
'enabled': BOOLEAN
|
||||
},
|
||||
'_all': {
|
||||
'enabled': BOOLEAN
|
||||
},
|
||||
'_field_names': {
|
||||
'index': BOOLEAN
|
||||
},
|
||||
'_routing': {
|
||||
'required': BOOLEAN,
|
||||
},
|
||||
'_index': {
|
||||
'enabled': BOOLEAN
|
||||
},
|
||||
'_parent': {
|
||||
__template: {
|
||||
'type': ''
|
||||
},
|
||||
'type': '{type}'
|
||||
},
|
||||
'_timestamp': {
|
||||
'enabled': BOOLEAN,
|
||||
'format': 'YYYY-MM-dd',
|
||||
'default': ""
|
||||
},
|
||||
'dynamic_date_formats': ['yyyy-MM-dd'],
|
||||
'date_detection': BOOLEAN,
|
||||
'numeric_detection': BOOLEAN,
|
||||
'properties': {
|
||||
'*': {
|
||||
type: {
|
||||
__one_of: ['text', 'keyword', 'float', 'double', 'byte', 'short', 'integer', 'long', 'date', 'boolean',
|
||||
'binary', 'object', 'nested', "geo_point", "geo_shape"
|
||||
]
|
||||
},
|
||||
|
||||
// strings
|
||||
store: BOOLEAN,
|
||||
index: BOOLEAN,
|
||||
term_vector: {
|
||||
__one_of: ['no', 'yes', 'with_offsets', 'with_positions', 'with_positions_offsets']
|
||||
},
|
||||
boost: 1.0,
|
||||
null_value: '',
|
||||
|
||||
norms: BOOLEAN,
|
||||
|
||||
index_options: {
|
||||
__one_of: ['docs', 'freqs', 'positions']
|
||||
},
|
||||
analyzer: 'standard',
|
||||
search_analyzer: 'standard',
|
||||
include_in_all: {
|
||||
__one_of: [false, true]
|
||||
},
|
||||
ignore_above: 10,
|
||||
position_increment_gap: 0,
|
||||
|
||||
// numeric
|
||||
precision_step: 4,
|
||||
ignore_malformed: BOOLEAN,
|
||||
|
||||
// geo_point
|
||||
lat_lon: {
|
||||
__one_of: [true, false]
|
||||
},
|
||||
geohash: {
|
||||
__one_of: [true, false]
|
||||
},
|
||||
geohash_precision: '1m',
|
||||
geohash_prefix: {
|
||||
__one_of: [true, false]
|
||||
},
|
||||
validate: {
|
||||
__one_of: [true, false]
|
||||
},
|
||||
validate_lat: {
|
||||
__one_of: [true, false]
|
||||
},
|
||||
validate_lon: {
|
||||
__one_of: [true, false]
|
||||
},
|
||||
normalize: {
|
||||
__one_of: [true, false]
|
||||
},
|
||||
normalize_lat: {
|
||||
__one_of: [true, false]
|
||||
},
|
||||
normalize_lon: {
|
||||
__one_of: [true, false]
|
||||
},
|
||||
|
||||
// geo_shape
|
||||
tree: {
|
||||
__one_of: ['geohash', 'quadtree']
|
||||
},
|
||||
precision: '5km',
|
||||
tree_levels: 12,
|
||||
distance_error_pct: 0.025,
|
||||
orientation: 'ccw',
|
||||
|
||||
// dates
|
||||
format: {
|
||||
__one_of: _.flatten([_.map(['date', 'date_time', 'date_time_no_millis',
|
||||
'ordinal_date', 'ordinal_date_time', 'ordinal_date_time_no_millis',
|
||||
'time', 'time_no_millis', 't_time', 't_time_no_millis',
|
||||
'week_date', 'week_date_time', 'week_date_time_no_millis'], function (s) {
|
||||
return ['basic_' + s, 'strict_' + s];
|
||||
}),
|
||||
[
|
||||
'date', 'date_hour', 'date_hour_minute', 'date_hour_minute_second', 'date_hour_minute_second_fraction',
|
||||
'date_hour_minute_second_millis', 'date_optional_time', 'date_time', 'date_time_no_millis',
|
||||
'hour', 'hour_minute', 'hour_minute_second', 'hour_minute_second_fraction', 'hour_minute_second_millis',
|
||||
'ordinal_date', 'ordinal_date_time', 'ordinal_date_time_no_millis', 'time', 'time_no_millis',
|
||||
't_time', 't_time_no_millis', 'week_date', 'week_date_time', 'weekDateTimeNoMillis', 'week_year',
|
||||
'weekyearWeek', 'weekyearWeekDay', 'year', 'year_month', 'year_month_day', 'epoch_millis', 'epoch_second'
|
||||
]])
|
||||
},
|
||||
|
||||
fielddata: {
|
||||
filter: {
|
||||
regex: '',
|
||||
frequency: {
|
||||
min: 0.001,
|
||||
max: 0.1,
|
||||
min_segment_size: 500
|
||||
}
|
||||
}
|
||||
},
|
||||
similarity: {
|
||||
__one_of: ['default', 'BM25']
|
||||
},
|
||||
|
||||
// objects
|
||||
properties: {
|
||||
__scope_link: '_put_mapping.{type}.properties'
|
||||
},
|
||||
|
||||
// multi_field
|
||||
fields: {
|
||||
'*': {
|
||||
__scope_link: '_put_mapping.type.properties.field'
|
||||
}
|
||||
},
|
||||
copy_to: {__one_of: ['{field}', ['{field}']]},
|
||||
|
||||
// nested
|
||||
include_in_parent: BOOLEAN,
|
||||
include_in_root: BOOLEAN
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
api.addEndpointDescription('_put_mapping', {
|
||||
methods: ['PUT'],
|
||||
patterns: [
|
||||
"{indices}/_mapping"
|
||||
],
|
||||
data_autocomplete_rules: {
|
||||
'{type}': {
|
||||
__scope_link: '_put_type_mapping'
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
76
src/plugins/console/api_server/es_5_0/nodes.js
Normal file
76
src/plugins/console/api_server/es_5_0/nodes.js
Normal file
|
@ -0,0 +1,76 @@
|
|||
module.exports = function (api) {
|
||||
api.addEndpointDescription('_nodes/hot_threads', {
|
||||
methods: ['GET'],
|
||||
patterns: [
|
||||
"_nodes/hot_threads",
|
||||
"_nodes/{nodes}/hot_threads"
|
||||
]
|
||||
});
|
||||
api.addEndpointDescription('_nodes/info', {
|
||||
patterns: [
|
||||
"_nodes",
|
||||
"_nodes/{metrics}",
|
||||
"_nodes/{nodes}",
|
||||
"_nodes/{nodes}/{metrics}",
|
||||
"_nodes/{nodes}/info/{metrics}"
|
||||
],
|
||||
url_components: {
|
||||
"metrics": [
|
||||
"settings",
|
||||
"os",
|
||||
"process",
|
||||
"jvm",
|
||||
"thread_pool",
|
||||
"network",
|
||||
"transport",
|
||||
"http",
|
||||
"plugins",
|
||||
"_all"
|
||||
]
|
||||
}
|
||||
});
|
||||
api.addEndpointDescription('_nodes/stats', {
|
||||
patterns: [
|
||||
"_nodes/stats",
|
||||
"_nodes/stats/{metrics}",
|
||||
"_nodes/stats/{metrics}/{index_metric}",
|
||||
"_nodes/{nodes}/stats",
|
||||
"_nodes/{nodes}/stats/{metrics}",
|
||||
"_nodes/{nodes}/stats/{metrics}/{index_metric}"
|
||||
],
|
||||
url_components: {
|
||||
"metrics": [
|
||||
"os",
|
||||
"jvm",
|
||||
"thread_pool",
|
||||
"network",
|
||||
"fs",
|
||||
"transport",
|
||||
"http",
|
||||
"indices",
|
||||
"process",
|
||||
"breaker",
|
||||
"_all"
|
||||
],
|
||||
"index_metric": [
|
||||
"store",
|
||||
"indexing",
|
||||
"get",
|
||||
"search",
|
||||
"merge",
|
||||
"flush",
|
||||
"refresh",
|
||||
"filter_cache",
|
||||
"fielddata",
|
||||
"docs",
|
||||
"warmer",
|
||||
"percolate",
|
||||
"completion",
|
||||
"segments",
|
||||
"translog",
|
||||
"query_cache",
|
||||
"_all"
|
||||
]
|
||||
}
|
||||
});
|
||||
};
|
90
src/plugins/console/api_server/es_5_0/percolator.js
Normal file
90
src/plugins/console/api_server/es_5_0/percolator.js
Normal file
|
@ -0,0 +1,90 @@
|
|||
module.exports = function (api) {
|
||||
api.addEndpointDescription('_put_percolator', {
|
||||
priority: 10, // to override doc
|
||||
methods: ['PUT', 'POST'],
|
||||
patterns: [
|
||||
"{index}/.percolator/{id}"
|
||||
],
|
||||
url_params: {
|
||||
"version": 1,
|
||||
"version_type": ["external", "internal"],
|
||||
"op_type": ["create"],
|
||||
"routing": "",
|
||||
"parent": "",
|
||||
"timestamp": "",
|
||||
"ttl": "5m",
|
||||
"consistency": ["qurom", "one", "all"],
|
||||
"refresh": "__flag__",
|
||||
"timeout": "1m"
|
||||
},
|
||||
data_autocomplete_rules: {
|
||||
query: {}
|
||||
}
|
||||
});
|
||||
api.addEndpointDescription('_percolate', {
|
||||
methods: ['GET', 'POST'],
|
||||
priority: 10, // to override doc
|
||||
patterns: [
|
||||
"{indices}/{type}/_percolate"
|
||||
],
|
||||
url_params: {
|
||||
preference: ["_primary", "_primary_first", "_local", "_only_node:xyz", "_prefer_node:xyz", "_shards:2,3"],
|
||||
routing: "",
|
||||
ignore_unavailable: ["true", "false"],
|
||||
percolate_format: ["ids"]
|
||||
},
|
||||
data_autocomplete_rules: {
|
||||
doc: {},
|
||||
query: {},
|
||||
filter: {},
|
||||
size: 10,
|
||||
track_scores: {__one_of: [true, false]},
|
||||
sort: "_score",
|
||||
aggs: {},
|
||||
highlight: {}
|
||||
}
|
||||
});
|
||||
api.addEndpointDescription('_percolate_id', {
|
||||
methods: ['GET', 'POST'],
|
||||
patterns: [
|
||||
"{indices}/{type}/{id}/_percolate"
|
||||
],
|
||||
url_params: {
|
||||
routing: "",
|
||||
ignore_unavailable: ["true", "false"],
|
||||
percolate_format: ["ids"],
|
||||
percolate_index: "{index}",
|
||||
percolate_type: "{type}",
|
||||
percolate_routing: "",
|
||||
percolate_preference: ["_primary", "_primary_first", "_local", "_only_node:xyz", "_prefer_node:xyz", "_shards:2,3"],
|
||||
version: 1,
|
||||
version_type: ["external", "internal"]
|
||||
},
|
||||
data_autocomplete_rules: {
|
||||
query: {},
|
||||
filter: {},
|
||||
size: 10,
|
||||
track_scores: {__one_of: [true, false]},
|
||||
sort: "_score",
|
||||
aggs: {},
|
||||
highlight: {}
|
||||
}
|
||||
});
|
||||
api.addEndpointDescription('_percolate_count', {
|
||||
methods: ['GET', 'POST'],
|
||||
patterns: [
|
||||
"{indices}/{type}/_percolate/count"
|
||||
],
|
||||
url_params: {
|
||||
preference: ["_primary", "_primary_first", "_local", "_only_node:xyz", "_prefer_node:xyz", "_shards:2,3"],
|
||||
routing: "",
|
||||
ignore_unavailable: ["true", "false"],
|
||||
percolate_format: ["ids"]
|
||||
},
|
||||
data_autocomplete_rules: {
|
||||
doc: {},
|
||||
query: {},
|
||||
filter: {}
|
||||
}
|
||||
});
|
||||
};
|
618
src/plugins/console/api_server/es_5_0/query.js
Normal file
618
src/plugins/console/api_server/es_5_0/query.js
Normal file
|
@ -0,0 +1,618 @@
|
|||
let _ = require("lodash");
|
||||
|
||||
var SPAN_QUERIES = {
|
||||
// TODO add one_of for objects
|
||||
span_first: {
|
||||
__scope_link: '.span_first'
|
||||
},
|
||||
span_near: {
|
||||
__scope_link: '.span_near'
|
||||
},
|
||||
span_or: {
|
||||
__scope_link: '.span_or'
|
||||
},
|
||||
span_not: {
|
||||
__scope_link: '.span_not'
|
||||
},
|
||||
span_term: {
|
||||
__scope_link: '.span_term'
|
||||
},
|
||||
span_containing: {
|
||||
__scope_link: '.span_containing'
|
||||
},
|
||||
span_within: {
|
||||
__scope_link: '.span_within'
|
||||
}
|
||||
};
|
||||
|
||||
var DECAY_FUNC_DESC = {
|
||||
__template: {
|
||||
"FIELD": {
|
||||
"origin": "",
|
||||
"scale": ""
|
||||
}
|
||||
},
|
||||
"{field}": {
|
||||
"origin": "",
|
||||
"scale": "",
|
||||
"offset": "",
|
||||
"decay": 0.5
|
||||
}
|
||||
},
|
||||
SCORING_FUNCS = {
|
||||
"script_score": {
|
||||
__template: {
|
||||
"script": "_score * doc['f'].value"
|
||||
},
|
||||
"script": {
|
||||
//populated by a global rule
|
||||
}
|
||||
},
|
||||
"boost_factor": 2.0,
|
||||
"random_score": {
|
||||
"seed": 314159265359
|
||||
},
|
||||
"linear": DECAY_FUNC_DESC,
|
||||
"exp": DECAY_FUNC_DESC,
|
||||
"gauss": DECAY_FUNC_DESC,
|
||||
"field_value_factor": {
|
||||
__template: {
|
||||
"field": ""
|
||||
},
|
||||
"field": "{field}",
|
||||
"factor": 1.2,
|
||||
"modifier": {
|
||||
__one_of: ["none", "log", "log1p", "log2p", "ln", "ln1p", "ln2p", "square", "sqrt", "reciprocal"]
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = function (api) {
|
||||
api.addGlobalAutocompleteRules('query', {
|
||||
match: {
|
||||
__template: {
|
||||
'FIELD': 'TEXT'
|
||||
},
|
||||
'{field}': {
|
||||
'query': '',
|
||||
'operator': {
|
||||
__one_of: ['and', 'or']
|
||||
},
|
||||
'type': {
|
||||
__one_of: ['phrase', 'phrase_prefix', 'boolean']
|
||||
},
|
||||
'max_expansions': 10,
|
||||
'analyzer': '',
|
||||
'fuzziness': 1.0,
|
||||
'prefix_length': 1
|
||||
}
|
||||
},
|
||||
match_phrase: {
|
||||
__template: {
|
||||
'FIELD': 'PHRASE'
|
||||
},
|
||||
'{field}': {
|
||||
query: '',
|
||||
analyzer: ''
|
||||
}
|
||||
},
|
||||
match_phrase_prefix: {
|
||||
__template: {
|
||||
'FIELD': 'PREFIX'
|
||||
},
|
||||
'{field}': {
|
||||
query: '',
|
||||
analyzer: '',
|
||||
max_expansions: 10,
|
||||
prefix_length: 1,
|
||||
fuzziness: 0.1
|
||||
}
|
||||
},
|
||||
multi_match: {
|
||||
__template: {
|
||||
'query': '',
|
||||
'fields': []
|
||||
},
|
||||
query: '',
|
||||
fields: ['{field}'],
|
||||
use_dis_max: {
|
||||
__template: true,
|
||||
__one_of: [true, false]
|
||||
},
|
||||
tie_breaker: 0.0,
|
||||
type: {__one_of: ['best_fields', 'most_fields', 'cross_fields', 'phrase', 'phrase_prefix']}
|
||||
},
|
||||
bool: {
|
||||
must: [
|
||||
{
|
||||
__scope_link: '.'
|
||||
}
|
||||
],
|
||||
must_not: [
|
||||
{
|
||||
__scope_link: '.'
|
||||
}
|
||||
],
|
||||
should: [
|
||||
{
|
||||
__scope_link: '.'
|
||||
}
|
||||
],
|
||||
filter: {
|
||||
__scope_link: 'GLOBAL.filter'
|
||||
},
|
||||
minimum_number_should_match: 1,
|
||||
boost: 1.0
|
||||
},
|
||||
boosting: {
|
||||
positive: {
|
||||
__scope_link: '.'
|
||||
},
|
||||
negative: {
|
||||
__scope_link: '.'
|
||||
},
|
||||
negative_boost: 0.2
|
||||
},
|
||||
ids: {
|
||||
type: '',
|
||||
values: []
|
||||
},
|
||||
constant_score: {
|
||||
__template: {
|
||||
filter: {},
|
||||
boost: 1.2
|
||||
},
|
||||
query: {},
|
||||
filter: {},
|
||||
boost: 1.2
|
||||
},
|
||||
dis_max: {
|
||||
__template: {
|
||||
tie_breaker: 0.7,
|
||||
boost: 1.2,
|
||||
queries: []
|
||||
},
|
||||
tie_breaker: 0.7,
|
||||
boost: 1.2,
|
||||
queries: [
|
||||
{
|
||||
__scope_link: '.'
|
||||
}
|
||||
]
|
||||
},
|
||||
field: {
|
||||
'{field}': {
|
||||
query: '',
|
||||
boost: 2.0,
|
||||
enable_position_increments: {
|
||||
__template: false,
|
||||
__one_of: [true, false]
|
||||
}
|
||||
}
|
||||
},
|
||||
fuzzy: {
|
||||
'{field}': {
|
||||
'value': '',
|
||||
'boost': 1.0,
|
||||
'fuzziness': 0.5,
|
||||
'prefix_length': 0
|
||||
}
|
||||
},
|
||||
has_child: {
|
||||
__template: {
|
||||
type: 'TYPE',
|
||||
query: {}
|
||||
},
|
||||
'type': '{type}',
|
||||
'score_mode': {
|
||||
__one_of: ['none', 'max', 'sum', 'avg']
|
||||
},
|
||||
'_scope': '',
|
||||
'query': {},
|
||||
'min_children': 1,
|
||||
'max_children': 10
|
||||
},
|
||||
has_parent: {
|
||||
__template: {
|
||||
parent_type: 'TYPE',
|
||||
query: {}
|
||||
},
|
||||
'parent_type': '{type}',
|
||||
'score_mode': {
|
||||
__one_of: ['none', 'score']
|
||||
},
|
||||
'_scope': '',
|
||||
'query': {}
|
||||
},
|
||||
match_all: {},
|
||||
more_like_this: {
|
||||
__template: {
|
||||
'fields': ['FIELD'],
|
||||
'like_text': 'text like this one',
|
||||
'min_term_freq': 1,
|
||||
'max_query_terms': 12
|
||||
},
|
||||
fields: ['{field}'],
|
||||
like_text: '',
|
||||
percent_terms_to_match: 0.3,
|
||||
min_term_freq: 2,
|
||||
max_query_terms: 25,
|
||||
stop_words: [''],
|
||||
min_doc_freq: 5,
|
||||
max_doc_freq: 100,
|
||||
min_word_len: 0,
|
||||
max_word_len: 0,
|
||||
boost_terms: 1,
|
||||
boost: 1.0,
|
||||
analyzer: '',
|
||||
docs: [{
|
||||
_index: "{index}",
|
||||
_type: "{type}",
|
||||
_id: ""
|
||||
}],
|
||||
ids: [""]
|
||||
},
|
||||
mlt: {
|
||||
__template: {
|
||||
'fields': ['FIELD'],
|
||||
'like_text': 'text like this one',
|
||||
'min_term_freq': 1,
|
||||
'max_query_terms': 12
|
||||
},
|
||||
__scope_link: ".more_like_this"
|
||||
},
|
||||
prefix: {
|
||||
__template: {
|
||||
'FIELD': {
|
||||
'value': ''
|
||||
}
|
||||
},
|
||||
'{field}': {
|
||||
value: '',
|
||||
boost: 1.0
|
||||
}
|
||||
},
|
||||
query_string: {
|
||||
__template: {
|
||||
'default_field': 'FIELD',
|
||||
'query': 'this AND that OR thus'
|
||||
},
|
||||
query: '',
|
||||
default_field: '{field}',
|
||||
fields: ['{field}'],
|
||||
default_operator: {
|
||||
__one_of: ['OR', 'AND']
|
||||
},
|
||||
analyzer: '',
|
||||
allow_leading_wildcard: {
|
||||
__one_of: [true, false]
|
||||
},
|
||||
lowercase_expanded_terms: {
|
||||
__one_of: [true, false]
|
||||
},
|
||||
enable_position_increments: {
|
||||
__one_of: [true, false]
|
||||
},
|
||||
fuzzy_max_expansions: 50,
|
||||
fuzziness: 0.5,
|
||||
fuzzy_prefix_length: 0,
|
||||
phrase_slop: 0,
|
||||
boost: 1.0,
|
||||
analyze_wildcard: {
|
||||
__one_of: [false, true]
|
||||
},
|
||||
auto_generate_phrase_queries: {
|
||||
__one_of: [false, true]
|
||||
},
|
||||
minimum_should_match: '20%',
|
||||
lenient: {
|
||||
__one_of: [false, true]
|
||||
},
|
||||
use_dis_max: {
|
||||
__one_of: [true, false]
|
||||
},
|
||||
tie_breaker: 0,
|
||||
time_zone: "+1:00"
|
||||
},
|
||||
simple_query_string: {
|
||||
__template: {
|
||||
query: "",
|
||||
fields: []
|
||||
},
|
||||
query: "",
|
||||
fields: ["{field}"],
|
||||
default_operator: {__one_of: ["OR", "AND"]},
|
||||
analyzer: "",
|
||||
flags: "OR|AND|PREFIX",
|
||||
lowercase_expanded_terms: {__one_of: [true, false]},
|
||||
locale: "ROOT",
|
||||
lenient: {__one_of: [true, false]}
|
||||
},
|
||||
range: {
|
||||
__template: {
|
||||
'FIELD': {
|
||||
gte: 10,
|
||||
lte: 20
|
||||
}
|
||||
},
|
||||
'{field}': {
|
||||
__template: {
|
||||
gte: 10,
|
||||
lte: 20
|
||||
},
|
||||
gte: 10,
|
||||
gt: 10,
|
||||
lte: 20,
|
||||
lt: 20,
|
||||
time_zone: "+1:00",
|
||||
boost: 1.0,
|
||||
"format": "dd/MM/yyyy||yyyy"
|
||||
|
||||
}
|
||||
},
|
||||
span_first: {
|
||||
__template: {
|
||||
'match': {
|
||||
'span_term': {
|
||||
'FIELD': 'VALUE'
|
||||
}
|
||||
},
|
||||
'end': 3
|
||||
},
|
||||
match: SPAN_QUERIES
|
||||
},
|
||||
span_near: {
|
||||
__template: {
|
||||
'clauses': [
|
||||
{
|
||||
span_term: {
|
||||
'FIELD': {
|
||||
'value': 'VALUE'
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
slop: 12,
|
||||
in_order: false
|
||||
},
|
||||
clauses: [
|
||||
SPAN_QUERIES
|
||||
],
|
||||
slop: 12,
|
||||
in_order: {
|
||||
__one_of: [false, true]
|
||||
},
|
||||
collect_payloads: {
|
||||
__one_of: [false, true]
|
||||
}
|
||||
},
|
||||
span_term: {
|
||||
__template: {
|
||||
'FIELD': {
|
||||
'value': 'VALUE'
|
||||
}
|
||||
},
|
||||
'{field}': {
|
||||
value: '',
|
||||
boost: 2.0
|
||||
}
|
||||
},
|
||||
span_not: {
|
||||
__template: {
|
||||
include: {
|
||||
span_term: {
|
||||
'FIELD': {
|
||||
'value': 'VALUE'
|
||||
}
|
||||
}
|
||||
},
|
||||
exclude: {
|
||||
span_term: {
|
||||
'FIELD': {
|
||||
'value': 'VALUE'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
include: SPAN_QUERIES,
|
||||
exclude: SPAN_QUERIES
|
||||
},
|
||||
span_or: {
|
||||
__template: {
|
||||
clauses: [
|
||||
{
|
||||
span_term: {
|
||||
'FIELD': {
|
||||
'value': 'VALUE'
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
clauses: [
|
||||
SPAN_QUERIES
|
||||
]
|
||||
},
|
||||
span_containing: {
|
||||
__template: {
|
||||
little: {
|
||||
span_term: {
|
||||
'FIELD': {
|
||||
'value': 'VALUE'
|
||||
}
|
||||
}
|
||||
},
|
||||
big: {
|
||||
span_near: {
|
||||
'clauses': [
|
||||
{
|
||||
span_term: {
|
||||
'FIELD': {
|
||||
'value': 'VALUE'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
span_term: {
|
||||
'FIELD': {
|
||||
'value': 'VALUE'
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"slop": 5,
|
||||
"in_order": false
|
||||
}
|
||||
}
|
||||
},
|
||||
little: SPAN_QUERIES,
|
||||
big: SPAN_QUERIES
|
||||
},
|
||||
span_within: {
|
||||
__template: {
|
||||
little: {
|
||||
span_term: {
|
||||
'FIELD': {
|
||||
'value': 'VALUE'
|
||||
}
|
||||
}
|
||||
},
|
||||
big: {
|
||||
span_near: {
|
||||
'clauses': [
|
||||
{
|
||||
span_term: {
|
||||
'FIELD': {
|
||||
'value': 'VALUE'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
span_term: {
|
||||
'FIELD': {
|
||||
'value': 'VALUE'
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"slop": 5,
|
||||
"in_order": false
|
||||
}
|
||||
}
|
||||
},
|
||||
little: SPAN_QUERIES,
|
||||
big: SPAN_QUERIES
|
||||
},
|
||||
term: {
|
||||
__template: {
|
||||
'FIELD': {
|
||||
value: 'VALUE'
|
||||
}
|
||||
},
|
||||
'{field}': {
|
||||
value: '',
|
||||
boost: 2.0
|
||||
}
|
||||
},
|
||||
terms: {
|
||||
__template: {
|
||||
'FIELD': ['VALUE1', 'VALUE2']
|
||||
},
|
||||
'{field}': ['']
|
||||
},
|
||||
wildcard: {
|
||||
__template: {
|
||||
'FIELD': {
|
||||
value: 'VALUE'
|
||||
}
|
||||
},
|
||||
'{field}': {
|
||||
value: '',
|
||||
boost: 2.0
|
||||
}
|
||||
},
|
||||
nested: {
|
||||
__template: {
|
||||
path: 'path_to_nested_doc',
|
||||
query: {}
|
||||
},
|
||||
path: '',
|
||||
query: {},
|
||||
score_mode: {
|
||||
__one_of: ['avg', 'total', 'max', 'none']
|
||||
}
|
||||
},
|
||||
custom_filters_score: {
|
||||
__template: {
|
||||
query: {},
|
||||
filters: [
|
||||
{
|
||||
filter: {}
|
||||
}
|
||||
]
|
||||
},
|
||||
query: {},
|
||||
filters: [
|
||||
{
|
||||
filter: {},
|
||||
boost: 2.0,
|
||||
script: {
|
||||
//populated by a global rule
|
||||
}
|
||||
}
|
||||
],
|
||||
score_mode: {
|
||||
__one_of: ['first', 'min', 'max', 'total', 'avg', 'multiply']
|
||||
},
|
||||
max_boost: 2.0,
|
||||
params: {},
|
||||
lang: ''
|
||||
},
|
||||
indices: {
|
||||
__template: {
|
||||
indices: ['INDEX1', 'INDEX2'],
|
||||
query: {}
|
||||
},
|
||||
indices: ['{index}'],
|
||||
query: {},
|
||||
no_match_query: {
|
||||
__scope_link: '.'
|
||||
}
|
||||
},
|
||||
geo_shape: {
|
||||
__template: {
|
||||
location: {},
|
||||
relation: 'within'
|
||||
},
|
||||
__scope_link: '.filter.geo_shape'
|
||||
},
|
||||
// js hint gets confused here
|
||||
/* jshint -W015 */
|
||||
function_score: _.defaults({
|
||||
__template: {
|
||||
query: {},
|
||||
functions: [
|
||||
{}
|
||||
]
|
||||
},
|
||||
query: {},
|
||||
functions: [
|
||||
_.defaults(
|
||||
{
|
||||
filter: {},
|
||||
weight: 1.0
|
||||
},
|
||||
SCORING_FUNCS
|
||||
)
|
||||
],
|
||||
boost: 1.0,
|
||||
boost_mode: {__one_of: ["multiply", "replace", "sum", "avg", "max", "min"]},
|
||||
score_mode: {__one_of: ["multiply", "sum", "first", "avg", "max", "min"]},
|
||||
max_boost: 10,
|
||||
min_score: 1.0
|
||||
},
|
||||
SCORING_FUNCS
|
||||
)
|
||||
|
||||
});
|
||||
};
|
255
src/plugins/console/api_server/es_5_0/search.js
Normal file
255
src/plugins/console/api_server/es_5_0/search.js
Normal file
|
@ -0,0 +1,255 @@
|
|||
module.exports = function (api) {
|
||||
api.addEndpointDescription('_search', {
|
||||
methods: ['GET', 'POST'],
|
||||
priority: 10, // collides with get doc by id
|
||||
patterns: [
|
||||
"{indices}/{types}/_search",
|
||||
"{indices}/_search",
|
||||
"_search"
|
||||
],
|
||||
url_params: {
|
||||
q: "",
|
||||
df: "",
|
||||
analyzer: "",
|
||||
default_operator: ["AND", "OR"],
|
||||
explain: "__flag__",
|
||||
_source: "",
|
||||
_source_include: "",
|
||||
_source_exclude: "",
|
||||
fields: [],
|
||||
sort: "",
|
||||
track_scores: "__flag__",
|
||||
timeout: 1,
|
||||
from: 0,
|
||||
size: 10,
|
||||
search_type: ["dfs_query_then_fetch", "dfs_query_and_fetch", "query_then_fetch", "query_and_fetch"],
|
||||
terminate_after: 10,
|
||||
lowercase_expanded_terms: ["true", "false"],
|
||||
analyze_wildcard: "__flag__",
|
||||
preference: ["_primary", "_primary_first", "_local", "_only_node:xyz", "_prefer_node:xyz", "_shards:2,3"],
|
||||
scroll: "5m",
|
||||
scroll_id: "",
|
||||
routing: "",
|
||||
request_cache: ["true", "false"]
|
||||
},
|
||||
data_autocomplete_rules: {
|
||||
query: {
|
||||
// populated by a global rule
|
||||
},
|
||||
aggs: {
|
||||
__template: {
|
||||
"NAME": {
|
||||
"AGG_TYPE": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
post_filter: {
|
||||
__scope_link: 'GLOBAL.filter'
|
||||
},
|
||||
size: {
|
||||
__template: 20
|
||||
},
|
||||
from: 0,
|
||||
sort: {
|
||||
__template: [
|
||||
{
|
||||
'FIELD': {
|
||||
'order': 'desc'
|
||||
}
|
||||
}
|
||||
],
|
||||
__any_of: [
|
||||
{
|
||||
'{field}': {
|
||||
'order': {
|
||||
__one_of: ['desc', 'asc']
|
||||
},
|
||||
missing: {
|
||||
__one_of: ['_last', '_first']
|
||||
},
|
||||
mode: {
|
||||
__one_of: ['min', 'max', 'avg', 'sum']
|
||||
},
|
||||
nested_path: "",
|
||||
nested_filter: {
|
||||
__scope_link: "GLOBAL.filter"
|
||||
}
|
||||
}
|
||||
},
|
||||
'{field}',
|
||||
'_score',
|
||||
{
|
||||
'_geo_distance': {
|
||||
__template: {
|
||||
"FIELD": {
|
||||
lat: 40,
|
||||
lon: -70
|
||||
},
|
||||
order: "asc"
|
||||
},
|
||||
"{field}": {
|
||||
__one_of: [
|
||||
{
|
||||
__template: {
|
||||
lat: 40,
|
||||
lon: -70
|
||||
},
|
||||
lat: 40,
|
||||
lon: -70
|
||||
},
|
||||
[
|
||||
{
|
||||
__template: {
|
||||
lat: 40,
|
||||
lon: -70
|
||||
},
|
||||
lat: 40,
|
||||
lon: -70
|
||||
}
|
||||
],
|
||||
[""],
|
||||
""
|
||||
]
|
||||
},
|
||||
distance_type: {__one_of: ["sloppy_arc", "arc", "plane"]},
|
||||
sort_mode: {__one_of: ["min", "max", "avg"]},
|
||||
order: {__one_of: ["asc", "desc"]},
|
||||
unit: "km"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
fields: ['{field}'],
|
||||
fielddata_fields: ["{field}"],
|
||||
script_fields: {
|
||||
__template: {
|
||||
'FIELD': {
|
||||
'script': {
|
||||
// populated by a global rule
|
||||
}
|
||||
}
|
||||
},
|
||||
'*': {
|
||||
__scope_link: 'GLOBAL.script'
|
||||
}
|
||||
},
|
||||
partial_fields: {
|
||||
__template: {
|
||||
'NAME': {
|
||||
include: []
|
||||
}
|
||||
},
|
||||
'*': {
|
||||
include: [],
|
||||
exclude: []
|
||||
}
|
||||
},
|
||||
highlight: {
|
||||
// populated by a global rule
|
||||
},
|
||||
_source: {
|
||||
__one_of: [
|
||||
"{field}",
|
||||
["{field}"],
|
||||
{
|
||||
"include": {
|
||||
__one_of: [
|
||||
"{field}",
|
||||
["{field}"]
|
||||
]
|
||||
},
|
||||
"exclude": {
|
||||
__one_of: [
|
||||
"{field}",
|
||||
["{field}"]
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
explain: {
|
||||
__one_of: [true, false]
|
||||
},
|
||||
stats: [''],
|
||||
timeout: "1s",
|
||||
version: {__one_of: [true, false]}
|
||||
}
|
||||
});
|
||||
|
||||
api.addEndpointDescription('_search_template', {
|
||||
methods: ['GET'],
|
||||
patterns: [
|
||||
"{indices}/{types}/_search/template",
|
||||
"{indices}/_search/template",
|
||||
"_search/template"
|
||||
],
|
||||
data_autocomplete_rules: {
|
||||
"template": {
|
||||
__one_of: [
|
||||
{__scope_link: "_search"},
|
||||
{__scope_link: "GLOBAL.script"}
|
||||
]
|
||||
},
|
||||
"params": {}
|
||||
}
|
||||
});
|
||||
|
||||
api.addEndpointDescription('_render_search_template', {
|
||||
methods: ['GET'],
|
||||
patterns: [
|
||||
"_render/template"
|
||||
],
|
||||
data_autocomplete_rules: {
|
||||
__one_of: [
|
||||
{"inline": {__scope_link: "_search"}},
|
||||
{__scope_link: "GLOBAL.script"}
|
||||
],
|
||||
"params": {}
|
||||
}
|
||||
});
|
||||
|
||||
api.addEndpointDescription('_render_search_template_with_id', {
|
||||
methods: ['GET'],
|
||||
patterns: [
|
||||
"_render/template/{id}"
|
||||
],
|
||||
data_autocomplete_rules: {
|
||||
"params": {}
|
||||
}
|
||||
});
|
||||
|
||||
api.addEndpointDescription('_get_delete_search_template', {
|
||||
methods: ['GET', 'DELETE'],
|
||||
patterns: [
|
||||
"_search/template/{id}"
|
||||
]
|
||||
});
|
||||
|
||||
api.addEndpointDescription('_put_search_template', {
|
||||
methods: ['PUT'],
|
||||
patterns: [
|
||||
"_search/template/{id}"
|
||||
],
|
||||
data_autocomplete_rules: {
|
||||
"template": {
|
||||
__scope_link: "_search"
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
api.addEndpointDescription('_search_shards', {
|
||||
methods: ['GET'],
|
||||
priority: 10, // collides with get doc by id
|
||||
patterns: [
|
||||
"{indices}/{types}/_search_shards",
|
||||
"{indices}/_search_shards",
|
||||
"_search_shards"
|
||||
],
|
||||
url_params: {
|
||||
preference: ["_primary", "_primary_first", "_local", "_only_node:xyz", "_prefer_node:xyz", "_shards:2,3"],
|
||||
routing: "",
|
||||
local: "__flag__"
|
||||
}
|
||||
});
|
||||
};
|
86
src/plugins/console/api_server/es_5_0/settings.js
Normal file
86
src/plugins/console/api_server/es_5_0/settings.js
Normal file
|
@ -0,0 +1,86 @@
|
|||
module.exports = function (api) {
|
||||
|
||||
api.addEndpointDescription('_get_settings', {
|
||||
patterns: [
|
||||
"{indices}/_settings",
|
||||
"_settings"
|
||||
],
|
||||
url_params: {
|
||||
flat_settings: "__flag__"
|
||||
}
|
||||
});
|
||||
api.addEndpointDescription('_put_settings', {
|
||||
methods: ['PUT'],
|
||||
patterns: [
|
||||
"{indices}/_settings",
|
||||
"_settings"
|
||||
],
|
||||
data_autocomplete_rules: {
|
||||
refresh_interval: '1s',
|
||||
number_of_shards: 5,
|
||||
number_of_replicas: 1,
|
||||
'blocks.read_only': {
|
||||
__one_of: [false, true]
|
||||
},
|
||||
'blocks.read': {
|
||||
__one_of: [true, false]
|
||||
},
|
||||
'blocks.write': {
|
||||
__one_of: [true, false]
|
||||
},
|
||||
'blocks.metadata': {
|
||||
__one_of: [true, false]
|
||||
},
|
||||
term_index_interval: 32,
|
||||
term_index_divisor: 1,
|
||||
'translog.flush_threshold_ops': 5000,
|
||||
'translog.flush_threshold_size': '200mb',
|
||||
'translog.flush_threshold_period': '30m',
|
||||
'translog.disable_flush': {
|
||||
__one_of: [true, false]
|
||||
},
|
||||
'cache.filter.max_size': '2gb',
|
||||
'cache.filter.expire': '2h',
|
||||
'gateway.snapshot_interval': '10s',
|
||||
routing: {
|
||||
allocation: {
|
||||
include: {
|
||||
tag: ''
|
||||
},
|
||||
exclude: {
|
||||
tag: ''
|
||||
},
|
||||
require: {
|
||||
tag: ''
|
||||
},
|
||||
total_shards_per_node: -1
|
||||
}
|
||||
},
|
||||
'recovery.initial_shards': {
|
||||
__one_of: ['quorum', 'quorum-1', 'half', 'full', 'full-1']
|
||||
},
|
||||
'ttl.disable_purge': {
|
||||
__one_of: [true, false]
|
||||
},
|
||||
analysis: {
|
||||
analyzer: {},
|
||||
tokenizer: {},
|
||||
filter: {},
|
||||
char_filter: {}
|
||||
},
|
||||
'cache.query.enable': {
|
||||
__one_of: [true, false]
|
||||
},
|
||||
shadow_replicas: {
|
||||
__one_of: [true, false]
|
||||
},
|
||||
shared_filesystem: {
|
||||
__one_of: [true, false]
|
||||
},
|
||||
data_path: 'path',
|
||||
codec: {
|
||||
__one_of: ['default', 'best_compression', 'lucene_default']
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
153
src/plugins/console/api_server/es_5_0/snapshot_restore.js
Normal file
153
src/plugins/console/api_server/es_5_0/snapshot_restore.js
Normal file
|
@ -0,0 +1,153 @@
|
|||
module.exports = function (api) {
|
||||
api.addEndpointDescription('restore_snapshot', {
|
||||
methods: ['POST'],
|
||||
patterns: [
|
||||
'_snapshot/{id}/{id}/_restore'
|
||||
],
|
||||
url_params: {
|
||||
wait_for_completion: "__flag__"
|
||||
},
|
||||
data_autocomplete_rules: {
|
||||
indices: "*",
|
||||
ignore_unavailable: {__one_of: [true, false]},
|
||||
include_global_state: false,
|
||||
rename_pattern: "index_(.+)",
|
||||
rename_replacement: "restored_index_$1"
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
api.addEndpointDescription('single_snapshot', {
|
||||
methods: ['GET', 'DELETE'],
|
||||
patterns: [
|
||||
'_snapshot/{id}/{id}'
|
||||
]
|
||||
});
|
||||
|
||||
api.addEndpointDescription('all_snapshots', {
|
||||
methods: ['GET'],
|
||||
patterns: [
|
||||
'_snapshot/{id}/_all'
|
||||
]
|
||||
});
|
||||
|
||||
api.addEndpointDescription('put_snapshot', {
|
||||
methods: ['PUT'],
|
||||
patterns: [
|
||||
'_snapshot/{id}/{id}'
|
||||
],
|
||||
url_params: {
|
||||
wait_for_completion: "__flag__"
|
||||
},
|
||||
data_autocomplete_rules: {
|
||||
indices: "*",
|
||||
ignore_unavailable: {__one_of: [true, false]},
|
||||
include_global_state: {__one_of: [true, false]},
|
||||
partial: {__one_of: [true, false]}
|
||||
}
|
||||
});
|
||||
|
||||
api.addEndpointDescription('_snapshot_status', {
|
||||
methods: ['GET'],
|
||||
patterns: [
|
||||
'_snapshot/_status',
|
||||
'_snapshot/{id}/_status',
|
||||
'_snapshot/{id}/{ids}/_status'
|
||||
]
|
||||
});
|
||||
|
||||
|
||||
function getRepositoryType(context, editor) {
|
||||
var iter = editor.iterForCurrentLoc();
|
||||
// for now just iterate back to the first "type" key
|
||||
var t = iter.getCurrentToken();
|
||||
var type;
|
||||
while (t && t.type.indexOf("url") < 0) {
|
||||
if (t.type === 'variable' && t.value === '"type"') {
|
||||
t = editor.parser.nextNonEmptyToken(iter);
|
||||
if (!t || t.type !== "punctuation.colon") {
|
||||
// weird place to be in, but safe choice..
|
||||
break;
|
||||
}
|
||||
t = editor.parser.nextNonEmptyToken(iter);
|
||||
if (t && t.type === "string") {
|
||||
type = t.value.replace(/"/g, '');
|
||||
}
|
||||
break;
|
||||
}
|
||||
t = editor.parser.prevNonEmptyToken(iter);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
api.addEndpointDescription('put_repository', {
|
||||
methods: ['PUT'],
|
||||
patterns: [
|
||||
'_snapshot/{id}'
|
||||
],
|
||||
data_autocomplete_rules: {
|
||||
__template: {"type": ""},
|
||||
|
||||
"type": {
|
||||
__one_of: ["fs", "url", "s3", "hdfs"]
|
||||
},
|
||||
"settings": {
|
||||
__one_of: [{
|
||||
//fs
|
||||
__condition: {
|
||||
lines_regex: String.raw`type["']\s*:\s*["']fs`
|
||||
},
|
||||
__template: {
|
||||
location: "path"
|
||||
},
|
||||
location: "path",
|
||||
compress: {__one_of: [true, false]},
|
||||
concurrent_streams: 5,
|
||||
chunk_size: "10m",
|
||||
max_restore_bytes_per_sec: "20mb",
|
||||
max_snapshot_bytes_per_sec: "20mb"
|
||||
},
|
||||
{// url
|
||||
__condition: {
|
||||
lines_regex: String.raw`type["']\s*:\s*["']url`
|
||||
},
|
||||
__template: {
|
||||
url: ""
|
||||
},
|
||||
url: "",
|
||||
concurrent_streams: 5
|
||||
},
|
||||
{ //s3
|
||||
__condition: {
|
||||
lines_regex: String.raw`type["']\s*:\s*["']s3`
|
||||
},
|
||||
__template: {
|
||||
bucket: ""
|
||||
},
|
||||
bucket: "",
|
||||
region: "",
|
||||
base_path: "",
|
||||
concurrent_streams: 5,
|
||||
chunk_size: "10m",
|
||||
compress: {__one_of: [true, false]}
|
||||
},
|
||||
{// hdfs
|
||||
__condition: {
|
||||
lines_regex: String.raw`type["']\s*:\s*["']hdfs`
|
||||
},
|
||||
__template: {
|
||||
path: ""
|
||||
},
|
||||
uri: "",
|
||||
path: "some/path",
|
||||
load_defaults: {__one_of: [true, false]},
|
||||
conf_location: "cfg.xml",
|
||||
concurrent_streams: 5,
|
||||
compress: {__one_of: [true, false]},
|
||||
chunk_size: "10m"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
27
src/plugins/console/api_server/es_5_0/templates.js
Normal file
27
src/plugins/console/api_server/es_5_0/templates.js
Normal file
|
@ -0,0 +1,27 @@
|
|||
module.exports = function (api) {
|
||||
api.addEndpointDescription('_delete_template', {
|
||||
methods: ['DELETE'],
|
||||
patterns: [
|
||||
"_template/{id}",
|
||||
]
|
||||
});
|
||||
api.addEndpointDescription('_get_template', {
|
||||
methods: ['GET'],
|
||||
patterns: [
|
||||
"_template/{id}",
|
||||
"_template",
|
||||
]
|
||||
});
|
||||
api.addEndpointDescription('_put_template', {
|
||||
methods: ['PUT'],
|
||||
patterns: [
|
||||
"_template/{id}",
|
||||
],
|
||||
data_autocomplete_rules: {
|
||||
template: 'index*',
|
||||
warmers: {__scope_link: '_warmer'},
|
||||
mappings: {__scope_link: '_put_mapping'},
|
||||
settings: {__scope_link: '_put_settings'}
|
||||
}
|
||||
});
|
||||
};
|
|
@ -16,7 +16,9 @@ module.exports = function (kibana) {
|
|||
main: 'plugins/console/console',
|
||||
icon: 'plugins/console/logo.svg',
|
||||
injectVars: function (server, options) {
|
||||
return options;
|
||||
const varsToInject = options;
|
||||
varsToInject.elasticsearchUrl = server.config().get('elasticsearch.url');
|
||||
return varsToInject;
|
||||
}
|
||||
}
|
||||
];
|
||||
|
@ -33,11 +35,11 @@ module.exports = function (kibana) {
|
|||
|
||||
return new kibana.Plugin({
|
||||
id: 'console',
|
||||
require: [ 'elasticsearch' ],
|
||||
|
||||
config: function (Joi) {
|
||||
return Joi.object({
|
||||
enabled: Joi.boolean().default(true),
|
||||
defaultServerUrl: Joi.string().default('http://localhost:9200'),
|
||||
proxyFilter: Joi.array().items(Joi.string()).single().default(['.*']),
|
||||
ssl: Joi.object({
|
||||
verify: Joi.boolean(),
|
||||
|
@ -88,10 +90,7 @@ module.exports = function (kibana) {
|
|||
const proxyRouteConfig = {
|
||||
validate: {
|
||||
query: Joi.object().keys({
|
||||
uri: Joi.string().uri({
|
||||
allowRelative: false,
|
||||
shema: ['http:', 'https:'],
|
||||
}),
|
||||
uri: Joi.string()
|
||||
}).unknown(true),
|
||||
},
|
||||
|
||||
|
@ -111,15 +110,23 @@ module.exports = function (kibana) {
|
|||
],
|
||||
|
||||
handler(req, reply) {
|
||||
const { uri } = req.query;
|
||||
let baseUri = server.config().get('elasticsearch.url');
|
||||
let { uri:path } = req.query;
|
||||
|
||||
baseUri = baseUri.replace(/\/+$/, '');
|
||||
path = path.replace(/^\/+/, '');
|
||||
const uri = baseUri + '/' + path;
|
||||
|
||||
const requestHeadersWhitelist = server.config().get('elasticsearch.requestHeadersWhitelist');
|
||||
const filterHeaders = server.plugins.elasticsearch.filterHeaders;
|
||||
reply.proxy({
|
||||
uri,
|
||||
mapUri: function (request, done) {
|
||||
done(null, uri, filterHeaders(request.headers, requestHeadersWhitelist))
|
||||
},
|
||||
xforward: true,
|
||||
passThrough: true,
|
||||
onResponse(err, res, request, reply, settings, ttl) {
|
||||
if (err != null) {
|
||||
reply("Error connecting to '" + request.query.uri + "':\n\n" + err.message).type("text/plain").statusCode = 502;
|
||||
reply("Error connecting to '" + uri + "':\n\n" + err.message).type("text/plain").statusCode = 502;
|
||||
} else {
|
||||
reply(null, res);
|
||||
}
|
||||
|
|
|
@ -10,15 +10,10 @@ let utils = require('./utils');
|
|||
let _ = require('lodash');
|
||||
const chrome = require('ui/chrome');
|
||||
|
||||
const defaultServerUrl = chrome.getInjected('defaultServerUrl');
|
||||
|
||||
$(document.body).removeClass('fouc');
|
||||
|
||||
// set the value of the server and/or the input and clear the output
|
||||
function resetToValues(server, content) {
|
||||
if (server != null) {
|
||||
es.setBaseUrl(server);
|
||||
}
|
||||
// set the value of the input and clear the output
|
||||
function resetToValues(content) {
|
||||
if (content != null) {
|
||||
input.update(content);
|
||||
}
|
||||
|
@ -31,10 +26,10 @@ function loadSavedState() {
|
|||
|
||||
if (sourceLocation == "stored") {
|
||||
if (previousSaveState) {
|
||||
resetToValues(previousSaveState.server, previousSaveState.content);
|
||||
resetToValues(previousSaveState.content);
|
||||
}
|
||||
else {
|
||||
resetToValues(defaultServerUrl);
|
||||
resetToValues();
|
||||
input.autoIndent();
|
||||
}
|
||||
}
|
||||
|
@ -44,17 +39,14 @@ function loadSavedState() {
|
|||
loadFrom.headers = {Accept: "application/vnd.github.v3.raw"};
|
||||
}
|
||||
$.ajax(loadFrom).done(function (data) {
|
||||
resetToValues(defaultServerUrl, data);
|
||||
resetToValues(data);
|
||||
input.moveToNextRequestEdge(true);
|
||||
input.highlightCurrentRequestsAndUpdateActionBar();
|
||||
input.updateActionsBar();
|
||||
});
|
||||
}
|
||||
else if (previousSaveState) {
|
||||
resetToValues(previousSaveState.server);
|
||||
}
|
||||
else {
|
||||
resetToValues(defaultServerUrl);
|
||||
resetToValues();
|
||||
}
|
||||
input.moveToNextRequestEdge(true);
|
||||
}
|
||||
|
@ -69,15 +61,12 @@ function setupAutosave() {
|
|||
}
|
||||
timer = setTimeout(saveCurrentState, saveDelay);
|
||||
});
|
||||
|
||||
es.addServerChangeListener(saveCurrentState);
|
||||
}
|
||||
|
||||
function saveCurrentState() {
|
||||
try {
|
||||
var content = input.getValue();
|
||||
var server = es.getBaseUrl();
|
||||
history.updateCurrentState(server, content);
|
||||
history.updateCurrentState(content);
|
||||
}
|
||||
catch (e) {
|
||||
console.log("Ignoring saving error: " + e);
|
||||
|
|
|
@ -13,7 +13,7 @@ module.run(function (Private, $rootScope) {
|
|||
|
||||
module.controller('SenseController', function SenseController($scope, docTitle) {
|
||||
|
||||
docTitle.change('Sense');
|
||||
docTitle.change('Console');
|
||||
|
||||
// require the root app code, which expects to execute once the dom is loaded up
|
||||
require('../app');
|
||||
|
@ -32,13 +32,4 @@ module.controller('SenseController', function SenseController($scope, docTitle)
|
|||
event.preventDefault();
|
||||
input.focus();
|
||||
};
|
||||
|
||||
this.serverUrl = es.getBaseUrl();
|
||||
|
||||
// read server url changes into scope
|
||||
es.addServerChangeListener((server) => {
|
||||
$scope.$evalAsync(() => {
|
||||
this.serverUrl = server;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<tabset>
|
||||
<tab heading="Request format">
|
||||
You can type one or more requests in the white editor. Sense understands requests in a compact format:
|
||||
You can type one or more requests in the white editor. Console understands requests in a compact format:
|
||||
<sense-help-example></sense-help-example>
|
||||
</tab>
|
||||
<tab heading="Keyboard tips">
|
||||
|
|
|
@ -7,27 +7,3 @@
|
|||
</span>
|
||||
</div>
|
||||
</kbn-top-nav>
|
||||
|
||||
<navbar ng-show="chrome.getVisible()" name="sense-serverInput">
|
||||
<form
|
||||
name="serverInput"
|
||||
class="fill inline-form"
|
||||
ng-submit="sense.sendSelected()"
|
||||
role="form">
|
||||
|
||||
<input
|
||||
type="text"
|
||||
placeholder="http://servername:port"
|
||||
aria-label="Server Name"
|
||||
class="form-control"
|
||||
ng-focus="navbar.updateServerUrlHistory()"
|
||||
ng-blur="navbar.commitServerUrlFormModel()"
|
||||
|
||||
sense-uib-typeahead="url for url in navbar.serverUrlHistory"
|
||||
ng-model="navbar.serverUrlFormModel"
|
||||
typeahead-append-to-body="true"
|
||||
typeahead-focus-first="false"
|
||||
|
||||
required>
|
||||
</form>
|
||||
</navbar>
|
||||
|
|
|
@ -14,7 +14,6 @@ require('ui/modules')
|
|||
scope: {},
|
||||
link($scope, $el, attrs, sense) {
|
||||
$scope.sense = sense
|
||||
$scope.navbar.link($scope)
|
||||
},
|
||||
controllerAs: 'navbar',
|
||||
controller: class SenseNavbarController {
|
||||
|
@ -49,21 +48,6 @@ require('ui/modules')
|
|||
this.menu.open('welcome')
|
||||
}
|
||||
|
||||
this.updateServerUrlHistory();
|
||||
}
|
||||
|
||||
link($scope) {
|
||||
$scope.$watch('sense.serverUrl', (url) => {
|
||||
this.serverUrlFormModel = url
|
||||
})
|
||||
}
|
||||
|
||||
updateServerUrlHistory() {
|
||||
this.serverUrlHistory = history.getHistoricalServers();
|
||||
}
|
||||
|
||||
commitServerUrlFormModel() {
|
||||
es.setBaseUrl(this.serverUrlFormModel);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
<h3>Welcome to Sense</h3>
|
||||
<h3>Welcome to Console</h3>
|
||||
|
||||
<h4>Quick intro to the UI</h4>
|
||||
|
||||
<p>Sense is split into two panes: an editor pane (left) and a response pane (right).
|
||||
<p>The Console UI is split into two panes: an editor pane (left) and a response pane (right).
|
||||
Use the editor to type requests and submit them to Elasticsearch. The results will be displayed in
|
||||
the response pane on the right side.
|
||||
</p>
|
||||
|
||||
<p>Sense understands requests in a compact format, similar to cURL:
|
||||
<p>Console understands requests in a compact format, similar to cURL:
|
||||
<sense-help-example></sense-help-example>
|
||||
|
||||
<p>While typing a request, Sense will make suggestions which you can than accept by hitting Enter/Tab.
|
||||
<p>While typing a request, Console will make suggestions which you can than accept by hitting Enter/Tab.
|
||||
These suggestions are made based on the request structure <i>as well as</i> your indices and types.
|
||||
</p>
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
|||
<ul>
|
||||
<li>Submit requests to ES using the green triangle button.</li>
|
||||
<li>Use the wrench menu for other useful things.</li>
|
||||
<li>You can paste requests in cURL format and they will be translated to the Sense syntax.</li>
|
||||
<li>You can paste requests in cURL format and they will be translated to the Console syntax.</li>
|
||||
<li>You can resize the editor and output panes by dragging the separator between them.</li>
|
||||
<li>Study the keyboard shortcuts under the Help button. Good stuff in there!</li>
|
||||
</ul>
|
||||
|
|
|
@ -1,13 +1,8 @@
|
|||
let _ = require('lodash');
|
||||
let $ = require('jquery');
|
||||
|
||||
let baseUrl;
|
||||
let serverChangeListeners = [];
|
||||
let esVersion = [];
|
||||
|
||||
module.exports.getBaseUrl = function () {
|
||||
return baseUrl;
|
||||
};
|
||||
module.exports.getVersion = function () {
|
||||
return esVersion;
|
||||
};
|
||||
|
@ -15,15 +10,7 @@ module.exports.getVersion = function () {
|
|||
module.exports.send = function (method, path, data, server, disable_auth_alert) {
|
||||
var wrappedDfd = $.Deferred();
|
||||
|
||||
server = server || exports.getBaseUrl();
|
||||
path = exports.constructESUrl(server, path);
|
||||
var uname_password_re = /^(https?:\/\/)?(?:(?:([^\/]*):)?([^\/]*?)@)?(.*)$/;
|
||||
var url_parts = path.match(uname_password_re);
|
||||
|
||||
var uname = url_parts[2];
|
||||
var password = url_parts[3];
|
||||
path = url_parts[1] + url_parts[4];
|
||||
console.log("Calling " + path + " (uname: " + uname + " pwd: " + password + ")");
|
||||
console.log("Calling " + path);
|
||||
if (data && method == "GET") {
|
||||
method = "POST";
|
||||
}
|
||||
|
@ -37,8 +24,6 @@ module.exports.send = function (method, path, data, server, disable_auth_alert)
|
|||
cache: false,
|
||||
crossDomain: true,
|
||||
type: method,
|
||||
password: password,
|
||||
username: uname,
|
||||
dataType: "text", // disable automatic guessing
|
||||
};
|
||||
|
||||
|
@ -49,68 +34,15 @@ module.exports.send = function (method, path, data, server, disable_auth_alert)
|
|||
},
|
||||
function (jqXHR, textStatus, errorThrown) {
|
||||
if (jqXHR.status == 0) {
|
||||
jqXHR.responseText = "\n\nFailed to connect to Sense's backend.\nPlease check the Kibana server is up and running";
|
||||
jqXHR.responseText = "\n\nFailed to connect to Console's backend.\nPlease check the Kibana server is up and running";
|
||||
}
|
||||
wrappedDfd.rejectWith(this, [jqXHR, textStatus, errorThrown]);
|
||||
});
|
||||
return wrappedDfd;
|
||||
};
|
||||
|
||||
module.exports.constructESUrl = function (server, path) {
|
||||
if (!path) {
|
||||
path = server;
|
||||
server = exports.getBaseUrl();
|
||||
}
|
||||
if (path.indexOf("://") >= 0) {
|
||||
return path;
|
||||
}
|
||||
if (server.indexOf("://") < 0) {
|
||||
server = (document.location.protocol || "http:") + "//" + server;
|
||||
}
|
||||
if (server.substr(-1) == "/") {
|
||||
server = server.substr(0, server.length - 1);
|
||||
}
|
||||
if (path.charAt(0) === "/") {
|
||||
path = path.substr(1);
|
||||
}
|
||||
|
||||
return server + "/" + path;
|
||||
};
|
||||
|
||||
module.exports.forceRefresh = function () {
|
||||
exports.setBaseUrl(baseUrl, true)
|
||||
};
|
||||
|
||||
module.exports.setBaseUrl = function (base, force) {
|
||||
if (baseUrl !== base || force) {
|
||||
var old = baseUrl;
|
||||
baseUrl = base;
|
||||
exports.send("GET", "/").done(function (data, status, xhr) {
|
||||
if (xhr.status === 200) {
|
||||
// parse for version
|
||||
var value = xhr.responseText;
|
||||
try {
|
||||
value = JSON.parse(value);
|
||||
if (value.version && value.version.number) {
|
||||
esVersion = value.version.number.split(".");
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
|
||||
}
|
||||
}
|
||||
_.each(serverChangeListeners, function (cb) {
|
||||
cb(base, old)
|
||||
});
|
||||
}).fail(function () {
|
||||
esVersion = []; // unknown
|
||||
_.each(serverChangeListeners, function (cb) {
|
||||
cb(base, old)
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
module.exports.addServerChangeListener = function (cb) {
|
||||
serverChangeListeners.push(cb);
|
||||
module.exports.constructESUrl = function (baseUri, path) {
|
||||
baseUri = baseUri.replace(/\/+$/, '');
|
||||
path = path.replace(/^\/+/, '');
|
||||
return baseUri + '/' + path;
|
||||
};
|
||||
|
|
|
@ -3,8 +3,6 @@ const { uniq } = require('lodash');
|
|||
const storage = require('./storage');
|
||||
const chrome = require('ui/chrome');
|
||||
|
||||
const defaultServerUrl = chrome.getInjected('defaultServerUrl');
|
||||
|
||||
const history = module.exports = {
|
||||
restoreFromHistory() {
|
||||
// default method for history.restoreFromHistory
|
||||
|
@ -26,11 +24,7 @@ const history = module.exports = {
|
|||
.map(key => storage.get(key));
|
||||
},
|
||||
|
||||
getHistoricalServers() {
|
||||
return uniq(history.getHistory().map(req => req.server));
|
||||
},
|
||||
|
||||
addToHistory(server, endpoint, method, data) {
|
||||
addToHistory(endpoint, method, data) {
|
||||
var keys = history.getHistoryKeys();
|
||||
keys.splice(0, 500); // only maintain most recent X;
|
||||
$.each(keys, function (i, k) {
|
||||
|
@ -41,18 +35,16 @@ const history = module.exports = {
|
|||
var k = "hist_elem_" + timestamp;
|
||||
storage.set(k, {
|
||||
time: timestamp,
|
||||
server: server,
|
||||
endpoint: endpoint,
|
||||
method: method,
|
||||
data: data
|
||||
});
|
||||
},
|
||||
|
||||
updateCurrentState(server, content) {
|
||||
updateCurrentState(content) {
|
||||
var timestamp = new Date().getTime();
|
||||
storage.set("editor_state", {
|
||||
time: timestamp,
|
||||
server: server === defaultServerUrl ? undefined : server,
|
||||
content: content
|
||||
});
|
||||
},
|
||||
|
@ -60,8 +52,8 @@ const history = module.exports = {
|
|||
getSavedEditorState() {
|
||||
const saved = storage.get('editor_state');
|
||||
if (!saved) return;
|
||||
const { time, server = defaultServerUrl, content } = saved;
|
||||
return { time, server, content };
|
||||
const { time, content } = saved;
|
||||
return { time, content };
|
||||
},
|
||||
|
||||
clearHistory($el) {
|
||||
|
|
|
@ -59,7 +59,7 @@ var zc = (function setupZeroClipboard() {
|
|||
|
||||
zc.on('wrongflash noflash', function () {
|
||||
if (!storage.get('flash_warning_shown')) {
|
||||
alert('Sense needs flash version 10.0 or greater in order to provide "Copy as cURL" functionality');
|
||||
alert('Console needs flash version 10.0 or greater in order to provide "Copy as cURL" functionality');
|
||||
storage.set('flash_warning_shown', 'true');
|
||||
}
|
||||
$copyAsCURL.hide();
|
||||
|
@ -158,7 +158,7 @@ function sendCurrentRequestToES() {
|
|||
((xhr.status >= 200 && xhr.status < 300) || xhr.status == 404)
|
||||
) {
|
||||
// we have someone on the other side. Add to history
|
||||
history.addToHistory(es.getBaseUrl(), es_path, es_method, es_data);
|
||||
history.addToHistory(es_path, es_method, es_data);
|
||||
|
||||
|
||||
let value = xhr.responseText;
|
||||
|
|
|
@ -238,29 +238,7 @@ function setActiveApi(api) {
|
|||
ACTIVE_API = api;
|
||||
}
|
||||
|
||||
es.addServerChangeListener(function () {
|
||||
var version = es.getVersion(), api;
|
||||
if (!version || version.length == 0) {
|
||||
api = "es_1_0";
|
||||
}
|
||||
else if (version[0] === "1") {
|
||||
api = "es_1_0";
|
||||
}
|
||||
else if (version[0] === "2") {
|
||||
api = "es_2_0";
|
||||
}
|
||||
else if (version[0] === "3") {
|
||||
api = "es_2_0"; // TODO: change :)
|
||||
}
|
||||
else {
|
||||
api = "es_1_0";
|
||||
}
|
||||
|
||||
if (api) {
|
||||
setActiveApi(api);
|
||||
}
|
||||
|
||||
});
|
||||
setActiveApi('es_5_0');
|
||||
|
||||
module.exports.setActiveApi = setActiveApi;
|
||||
module.exports.getGlobalAutocompleteComponents = getGlobalAutocompleteComponents;
|
||||
|
|
|
@ -279,8 +279,6 @@ function autocomplete_retriever() {
|
|||
}, 60000);
|
||||
}
|
||||
|
||||
es.addServerChangeListener(retrieveAutocompleteInfoFromServer);
|
||||
|
||||
module.exports = _.assign(mappingObj, {
|
||||
getFields: getFields,
|
||||
getIndices: getIndices,
|
||||
|
|
|
@ -6,6 +6,8 @@ let RowParser = require('./row_parser');
|
|||
let InputMode = require('./mode/input');
|
||||
let utils = require('../utils');
|
||||
let es = require('../es');
|
||||
import chrome from 'ui/chrome';
|
||||
|
||||
const smartResize = require('../smart_resize');
|
||||
|
||||
function isInt(x) {
|
||||
|
@ -538,7 +540,8 @@ function SenseEditor($el) {
|
|||
es_method = req.method,
|
||||
es_data = req.data;
|
||||
|
||||
var url = es.constructESUrl(es.getBaseUrl() || "localhost:9200", es_path);
|
||||
const elasticsearchBaseUrl = chrome.getInjected('elasticsearchUrl');
|
||||
var url = es.constructESUrl(elasticsearchBaseUrl, es_path);
|
||||
|
||||
var ret = 'curl -X' + es_method + ' "' + url + '"';
|
||||
if (es_data && es_data.length) {
|
||||
|
|
|
@ -61,7 +61,6 @@ function updateSettings({ fontSize, wrapMode, autocomplete}) {
|
|||
setWrapMode(wrapMode);
|
||||
setAutocomplete(autocomplete);
|
||||
require('./input').focus();
|
||||
es.forceRefresh();
|
||||
return getCurrentSettings();
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@ var {test, module, ok, fail, asyncTest, deepEqual, equal, start} = QUnit;
|
|||
|
||||
module("Editor", {
|
||||
setup: function () {
|
||||
es.setBaseUrl("http://localhost:9200");
|
||||
input.$el.show();
|
||||
input.autocomplete._test.removeChangeListener();
|
||||
|
||||
|
|
|
@ -489,7 +489,7 @@ context_tests(
|
|||
);
|
||||
|
||||
function tt(term, template, meta) {
|
||||
var term = {name: term, template: template};
|
||||
term = {name: term, template: template};
|
||||
if (meta) {
|
||||
term.meta = meta;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@ import healthCheck from './lib/health_check';
|
|||
import exposeClient from './lib/expose_client';
|
||||
import createProxy, { createPath } from './lib/create_proxy';
|
||||
|
||||
const DEFAULT_REQUEST_HEADERS = [ 'authorization' ];
|
||||
|
||||
module.exports = function ({ Plugin }) {
|
||||
return new Plugin({
|
||||
require: ['kibana'],
|
||||
|
@ -20,6 +22,7 @@ module.exports = function ({ Plugin }) {
|
|||
password: string(),
|
||||
shardTimeout: number().default(0),
|
||||
requestTimeout: number().default(30000),
|
||||
requestHeadersWhitelist: array().items().single().default(DEFAULT_REQUEST_HEADERS),
|
||||
pingTimeout: number().default(ref('requestTimeout')),
|
||||
startupTimeout: number().default(5000),
|
||||
ssl: object({
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import _ from 'lodash';
|
||||
import Promise from 'bluebird';
|
||||
import sinon from 'sinon';
|
||||
import expect from 'expect.js';
|
||||
import url from 'url';
|
||||
import SetupError from '../setup_error';
|
||||
|
||||
import serverConfig from '../../../../../test/server_config';
|
||||
import checkEsVersion from '../check_es_version';
|
||||
|
@ -67,20 +69,24 @@ describe('plugins/elasticsearch', function () {
|
|||
|
||||
it('fails with a single node that is out of date', function () {
|
||||
setNodes('1.4.4', '1.4.2', '1.4.5');
|
||||
return checkEsVersion(server)
|
||||
.then(function () {
|
||||
throw new Error('expected validation to fail');
|
||||
}, _.noop);
|
||||
|
||||
checkEsVersion(server)
|
||||
.catch(function (e) {
|
||||
expect(e).to.be.a(SetupError);
|
||||
});
|
||||
});
|
||||
|
||||
it('passes if that single node is a client node', function () {
|
||||
it('fails if that single node is a client node', function () {
|
||||
setNodes(
|
||||
'1.4.4',
|
||||
{ version: '1.4.2', attributes: { client: 'true' } },
|
||||
'1.4.5'
|
||||
);
|
||||
|
||||
return checkEsVersion(server);
|
||||
checkEsVersion(server)
|
||||
.catch(function (e) {
|
||||
expect(e).to.be.a(SetupError);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -18,6 +18,7 @@ describe('plugins/elasticsearch', function () {
|
|||
let plugin;
|
||||
let server;
|
||||
let get;
|
||||
let set;
|
||||
let client;
|
||||
|
||||
beforeEach(function () {
|
||||
|
@ -30,8 +31,9 @@ describe('plugins/elasticsearch', function () {
|
|||
yellow: sinon.stub()
|
||||
}
|
||||
};
|
||||
// setup the config().get() stub
|
||||
// setup the config().get()/.set() stubs
|
||||
get = sinon.stub();
|
||||
set = sinon.stub();
|
||||
// set up the elasticsearch client stub
|
||||
client = {
|
||||
cluster: { health: sinon.stub() },
|
||||
|
@ -39,6 +41,8 @@ describe('plugins/elasticsearch', function () {
|
|||
nodes: { info: sinon.stub() },
|
||||
ping: sinon.stub(),
|
||||
create: sinon.stub(),
|
||||
index: sinon.stub().returns(Promise.resolve()),
|
||||
get: sinon.stub().returns(Promise.resolve({ found: false })),
|
||||
search: sinon.stub().returns(Promise.resolve({ hits: { hits: [] } })),
|
||||
};
|
||||
client.nodes.info.returns(Promise.resolve({
|
||||
|
@ -53,8 +57,9 @@ describe('plugins/elasticsearch', function () {
|
|||
// Setup the server mock
|
||||
server = {
|
||||
log: sinon.stub(),
|
||||
config: function () { return { get: get }; },
|
||||
plugins: { elasticsearch: { client: client } }
|
||||
info: { port: 5601 },
|
||||
config: function () { return { get, set }; },
|
||||
plugins: { elasticsearch: { client } }
|
||||
};
|
||||
|
||||
health = healthCheck(plugin, server);
|
||||
|
|
90
src/plugins/elasticsearch/lib/__tests__/manage_uuid.js
Normal file
90
src/plugins/elasticsearch/lib/__tests__/manage_uuid.js
Normal file
|
@ -0,0 +1,90 @@
|
|||
import expect from 'expect.js';
|
||||
import sinon from 'sinon';
|
||||
import Joi from 'joi';
|
||||
import * as kbnTestServer from '../../../../../test/utils/kbn_server.js';
|
||||
import fromRoot from '../../../../utils/from_root';
|
||||
import manageUuid from '../manage_uuid';
|
||||
|
||||
describe('plugins/elasticsearch', function () {
|
||||
describe('manage_uuid', function () {
|
||||
const testUuid = 'c4add484-0cba-4e05-86fe-4baa112d9e53';
|
||||
let kbnServer;
|
||||
let config;
|
||||
|
||||
before(async function () {
|
||||
this.timeout(60000); // sometimes waiting for server takes longer than 10
|
||||
|
||||
kbnServer = kbnTestServer.createServer({
|
||||
plugins: {
|
||||
scanDirs: [
|
||||
fromRoot('src/plugins')
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
await kbnServer.ready();
|
||||
await kbnServer.server.plugins.elasticsearch.waitUntilReady();
|
||||
});
|
||||
|
||||
// clear uuid stuff from previous test runs
|
||||
beforeEach(function () {
|
||||
kbnServer.server.log = sinon.stub();
|
||||
kbnServer.server.log.reset();
|
||||
config = kbnServer.server.config();
|
||||
});
|
||||
|
||||
after(async function () {
|
||||
await kbnServer.close();
|
||||
});
|
||||
|
||||
it('ensure config uuid is validated as a guid', async function () {
|
||||
config.set('uuid', testUuid);
|
||||
expect(config.get('uuid')).to.be(testUuid);
|
||||
|
||||
expect(() => {
|
||||
config.set('uuid', 'foouid');
|
||||
}).to.throwException((e) => {
|
||||
expect(e.name).to.be('ValidationError');
|
||||
});
|
||||
});
|
||||
|
||||
it('finds the previously set uuid with config match', async function () {
|
||||
const uuidManagement = manageUuid(kbnServer.server);
|
||||
const msg = `Kibana instance UUID: ${testUuid}`;
|
||||
config.set('uuid', testUuid);
|
||||
|
||||
await uuidManagement();
|
||||
await uuidManagement();
|
||||
|
||||
expect(kbnServer.server.log.lastCall.args[1]).to.be.eql(msg);
|
||||
});
|
||||
|
||||
it('updates the previously set uuid with config value', async function () {
|
||||
const uuidManagement = manageUuid(kbnServer.server);
|
||||
config.set('uuid', testUuid);
|
||||
|
||||
await uuidManagement();
|
||||
|
||||
const newUuid = '5b2de169-2785-441b-ae8c-186a1936b17d';
|
||||
const msg = `Updating Kibana instance UUID to: ${newUuid} (was: ${testUuid})`;
|
||||
|
||||
config.set('uuid', newUuid);
|
||||
await uuidManagement();
|
||||
|
||||
expect(kbnServer.server.log.lastCall.args[1]).to.be(msg);
|
||||
});
|
||||
|
||||
it('resumes the uuid stored in data and sets it to the config', async function () {
|
||||
const uuidManagement = manageUuid(kbnServer.server);
|
||||
const partialMsg = 'Resuming persistent Kibana instance UUID';
|
||||
config.set('uuid'); // set to undefined
|
||||
|
||||
await uuidManagement();
|
||||
|
||||
expect(config.get('uuid')).to.be.ok(); // not undefined any more
|
||||
expect(kbnServer.server.log.lastCall.args[1]).to.match(new RegExp(`^${partialMsg}`));
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
});
|
76
src/plugins/elasticsearch/lib/__tests__/map_uri.js
Normal file
76
src/plugins/elasticsearch/lib/__tests__/map_uri.js
Normal file
|
@ -0,0 +1,76 @@
|
|||
import expect from 'expect.js';
|
||||
import mapUri from '../map_uri';
|
||||
import sinon from 'sinon';
|
||||
|
||||
describe('plugins/elasticsearch', function () {
|
||||
describe('lib/map_uri', function () {
|
||||
|
||||
let request;
|
||||
|
||||
beforeEach(function () {
|
||||
request = {
|
||||
path: '/elasticsearch/some/path',
|
||||
headers: {
|
||||
cookie: 'some_cookie_string',
|
||||
'accept-encoding': 'gzip, deflate',
|
||||
origin: 'https://localhost:5601',
|
||||
'content-type': 'application/json',
|
||||
'x-my-custom-header': '42',
|
||||
accept: 'application/json, text/plain, */*',
|
||||
authorization: '2343d322eda344390fdw42'
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
it('only sends the whitelisted request headers', function () {
|
||||
|
||||
const get = sinon.stub()
|
||||
.withArgs('elasticsearch.url').returns('http://foobar:9200')
|
||||
.withArgs('elasticsearch.requestHeadersWhitelist').returns(['x-my-custom-HEADER', 'Authorization']);
|
||||
const config = function () { return { get: get }; };
|
||||
const server = {
|
||||
config: config
|
||||
};
|
||||
|
||||
mapUri(server)(request, function (err, upstreamUri, upstreamHeaders) {
|
||||
expect(err).to.be(null);
|
||||
expect(upstreamHeaders).to.have.property('authorization');
|
||||
expect(upstreamHeaders).to.have.property('x-my-custom-header');
|
||||
expect(Object.keys(upstreamHeaders).length).to.be(2);
|
||||
});
|
||||
});
|
||||
|
||||
it('sends no headers if whitelist is set to []', function () {
|
||||
|
||||
const get = sinon.stub()
|
||||
.withArgs('elasticsearch.url').returns('http://foobar:9200')
|
||||
.withArgs('elasticsearch.requestHeadersWhitelist').returns([]);
|
||||
const config = function () { return { get: get }; };
|
||||
const server = {
|
||||
config: config
|
||||
};
|
||||
|
||||
mapUri(server)(request, function (err, upstreamUri, upstreamHeaders) {
|
||||
expect(err).to.be(null);
|
||||
expect(Object.keys(upstreamHeaders).length).to.be(0);
|
||||
});
|
||||
});
|
||||
|
||||
it('sends no headers if whitelist is set to no value', function () {
|
||||
|
||||
const get = sinon.stub()
|
||||
.withArgs('elasticsearch.url').returns('http://foobar:9200')
|
||||
.withArgs('elasticsearch.requestHeadersWhitelist').returns([ null ]); // This is how Joi returns it
|
||||
const config = function () { return { get: get }; };
|
||||
const server = {
|
||||
config: config
|
||||
};
|
||||
|
||||
mapUri(server)(request, function (err, upstreamUri, upstreamHeaders) {
|
||||
expect(err).to.be(null);
|
||||
expect(Object.keys(upstreamHeaders).length).to.be(0);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
});
|
|
@ -3,12 +3,12 @@ import Promise from 'bluebird';
|
|||
import Boom from 'boom';
|
||||
import getBasicAuthRealm from './get_basic_auth_realm';
|
||||
import toPath from 'lodash/internal/toPath';
|
||||
import filterHeaders from './filter_headers';
|
||||
|
||||
module.exports = (client) => {
|
||||
module.exports = (server, client) => {
|
||||
return (req, endpoint, params = {}) => {
|
||||
if (req.headers.authorization) {
|
||||
_.set(params, 'headers.authorization', req.headers.authorization);
|
||||
}
|
||||
const filteredHeaders = filterHeaders(req.headers, server.config().get('elasticsearch.requestHeadersWhitelist'));
|
||||
_.set(params, 'headers', filteredHeaders);
|
||||
const path = toPath(endpoint);
|
||||
const api = _.get(client, path);
|
||||
let apiContext = _.get(client, path.slice(0, -1));
|
||||
|
|
|
@ -12,12 +12,6 @@ module.exports = function (server) {
|
|||
return client.nodes.info()
|
||||
.then(function (info) {
|
||||
const badNodes = _.filter(info.nodes, function (node) {
|
||||
// remove client nodes (Logstash)
|
||||
const isClient = _.get(node, 'attributes.client');
|
||||
if (isClient != null && esBool(isClient) === true) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// remove nodes that satify required engine version
|
||||
return !versionSatisfies(node.version, engineVersion);
|
||||
});
|
||||
|
|
|
@ -16,10 +16,12 @@ function createProxy(server, method, route, config) {
|
|||
handler: {
|
||||
proxy: {
|
||||
mapUri: mapUri(server),
|
||||
passThrough: true,
|
||||
agent: createAgent(server),
|
||||
xforward: true,
|
||||
timeout: server.config().get('elasticsearch.requestTimeout')
|
||||
timeout: server.config().get('elasticsearch.requestTimeout'),
|
||||
onResponse: function (err, responseFromUpstream, request, reply) {
|
||||
reply(err, responseFromUpstream);
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
@ -5,6 +5,7 @@ const readFile = (file) => require('fs').readFileSync(file, 'utf8');
|
|||
import util from 'util';
|
||||
import url from 'url';
|
||||
import callWithRequest from './call_with_request';
|
||||
import filterHeaders from './filter_headers';
|
||||
|
||||
module.exports = function (server) {
|
||||
const config = server.config();
|
||||
|
@ -78,8 +79,9 @@ module.exports = function (server) {
|
|||
server.expose('ElasticsearchClientLogging', ElasticsearchClientLogging);
|
||||
server.expose('client', client);
|
||||
server.expose('createClient', createClient);
|
||||
server.expose('callWithRequestFactory', callWithRequest);
|
||||
server.expose('callWithRequest', callWithRequest(noAuthClient));
|
||||
server.expose('callWithRequestFactory', _.partial(callWithRequest, server));
|
||||
server.expose('callWithRequest', callWithRequest(server, noAuthClient));
|
||||
server.expose('filterHeaders', filterHeaders);
|
||||
server.expose('errors', elasticsearch.errors);
|
||||
|
||||
return client;
|
||||
|
|
22
src/plugins/elasticsearch/lib/filter_headers.js
Normal file
22
src/plugins/elasticsearch/lib/filter_headers.js
Normal file
|
@ -0,0 +1,22 @@
|
|||
import _ from 'lodash';
|
||||
|
||||
export default function (originalHeaders, headersToKeep) {
|
||||
|
||||
const normalizeHeader = function (header) {
|
||||
if (!header) {
|
||||
return '';
|
||||
}
|
||||
header = header.toString();
|
||||
return header.trim().toLowerCase();
|
||||
};
|
||||
|
||||
// Normalize list of headers we want to allow in upstream request
|
||||
const headersToKeepNormalized = headersToKeep.map(normalizeHeader);
|
||||
|
||||
// Normalize original headers in request
|
||||
const originalHeadersNormalized = _.mapKeys(originalHeaders, function (headerValue, headerName) {
|
||||
return normalizeHeader(headerName);
|
||||
});
|
||||
|
||||
return _.pick(originalHeaders, headersToKeepNormalized);
|
||||
}
|
|
@ -5,6 +5,7 @@ import exposeClient from './expose_client';
|
|||
import migrateConfig from './migrate_config';
|
||||
import createKibanaIndex from './create_kibana_index';
|
||||
import checkEsVersion from './check_es_version';
|
||||
import manageUuid from './manage_uuid';
|
||||
const NoConnections = elasticsearch.errors.NoConnections;
|
||||
import util from 'util';
|
||||
const format = util.format;
|
||||
|
@ -18,6 +19,7 @@ const REQUEST_DELAY = 2500;
|
|||
module.exports = function (plugin, server) {
|
||||
const config = server.config();
|
||||
const client = server.plugins.elasticsearch.client;
|
||||
const uuidManagement = manageUuid(server);
|
||||
|
||||
plugin.status.yellow('Waiting for Elasticsearch');
|
||||
|
||||
|
@ -76,16 +78,19 @@ module.exports = function (plugin, server) {
|
|||
plugin.status.red('Elasticsearch is still initializing the kibana index.');
|
||||
return Promise.delay(REQUEST_DELAY).then(waitForShards);
|
||||
}
|
||||
|
||||
// otherwise we are g2g
|
||||
plugin.status.green('Kibana index ready');
|
||||
});
|
||||
}
|
||||
|
||||
function setGreenStatus() {
|
||||
return plugin.status.green('Kibana index ready');
|
||||
}
|
||||
|
||||
function check() {
|
||||
return waitForPong()
|
||||
.then(_.partial(checkEsVersion, server))
|
||||
.then(waitForShards)
|
||||
.then(uuidManagement)
|
||||
.then(setGreenStatus)
|
||||
.then(_.partial(migrateConfig, server))
|
||||
.catch(err => plugin.status.red(err));
|
||||
}
|
||||
|
|
|
@ -6,5 +6,12 @@ export const mappings = {
|
|||
index: 'not_analyzed'
|
||||
}
|
||||
}
|
||||
},
|
||||
server: {
|
||||
properties: {
|
||||
uuid: {
|
||||
type: 'keyword'
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
81
src/plugins/elasticsearch/lib/manage_uuid.js
Normal file
81
src/plugins/elasticsearch/lib/manage_uuid.js
Normal file
|
@ -0,0 +1,81 @@
|
|||
import uuid from 'node-uuid';
|
||||
import { hostname } from 'os';
|
||||
const serverHostname = hostname();
|
||||
|
||||
/* Handle different scenarios:
|
||||
* - config uuid exists, data uuid exists and matches
|
||||
* - nothing to do
|
||||
* - config uuid missing, data uuid exists
|
||||
* - set uuid from data as config uuid
|
||||
* - config uuid exists, data uuid exists but mismatches
|
||||
* - update data uuid with config uuid
|
||||
* - config uuid missing, data uuid missing
|
||||
* - generate new uuid, set in config and insert in data
|
||||
* ("config uuid" = uuid in server.config,
|
||||
* "data uuid" = uuid in .kibana index)
|
||||
*/
|
||||
export default function manageUuid(server) {
|
||||
const TYPE = 'server';
|
||||
const config = server.config();
|
||||
const serverPort = server.info.port;
|
||||
const client = server.plugins.elasticsearch.client;
|
||||
|
||||
return function uuidManagement() {
|
||||
const fieldId = `${serverHostname}-${serverPort}`;
|
||||
const kibanaIndex = config.get('kibana.index');
|
||||
let kibanaUuid = config.get('uuid');
|
||||
|
||||
function logToServer(msg) {
|
||||
server.log(['server', 'uuid', fieldId], msg);
|
||||
}
|
||||
|
||||
return client.get({
|
||||
index: kibanaIndex,
|
||||
ignore: [404],
|
||||
type: TYPE,
|
||||
id: fieldId
|
||||
}).then(result => {
|
||||
if (result.found) {
|
||||
if (kibanaUuid === result._source.uuid) {
|
||||
// config uuid exists, data uuid exists and matches
|
||||
logToServer(`Kibana instance UUID: ${kibanaUuid}`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!kibanaUuid) {
|
||||
// config uuid missing, data uuid exists
|
||||
kibanaUuid = result._source.uuid;
|
||||
logToServer(`Resuming persistent Kibana instance UUID: ${kibanaUuid}`);
|
||||
config.set('uuid', kibanaUuid);
|
||||
return;
|
||||
}
|
||||
|
||||
if (kibanaUuid !== result._source.uuid) {
|
||||
// config uuid exists, data uuid exists but mismatches
|
||||
logToServer(`Updating Kibana instance UUID to: ${kibanaUuid} (was: ${result._source.uuid})`);
|
||||
return client.update({
|
||||
index: kibanaIndex,
|
||||
type: TYPE,
|
||||
id: fieldId,
|
||||
body: { doc: { uuid: kibanaUuid } }
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// data uuid missing
|
||||
if (!kibanaUuid) {
|
||||
// config uuid missing
|
||||
kibanaUuid = uuid.v4();
|
||||
config.set('uuid', kibanaUuid);
|
||||
}
|
||||
|
||||
logToServer(`Setting new Kibana instance UUID: ${kibanaUuid}`);
|
||||
return client.index({
|
||||
index: kibanaIndex,
|
||||
type: TYPE,
|
||||
id: fieldId,
|
||||
body: { uuid: kibanaUuid }
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
|
@ -1,6 +1,9 @@
|
|||
import querystring from 'querystring';
|
||||
import { resolve } from 'url';
|
||||
import filterHeaders from './filter_headers';
|
||||
|
||||
module.exports = function mapUri(server, prefix) {
|
||||
|
||||
const config = server.config();
|
||||
return function (request, done) {
|
||||
const path = request.path.replace('/elasticsearch', '');
|
||||
|
@ -11,6 +14,7 @@ module.exports = function mapUri(server, prefix) {
|
|||
}
|
||||
const query = querystring.stringify(request.query);
|
||||
if (query) url += '?' + query;
|
||||
done(null, url);
|
||||
const filteredHeaders = filterHeaders(request.headers, server.config().get('elasticsearch.requestHeadersWhitelist'));
|
||||
done(null, url, filteredHeaders);
|
||||
};
|
||||
};
|
||||
|
|
|
@ -106,6 +106,8 @@ describe('docViews', function () {
|
|||
expect($scope.filter.calledOnce).to.be(true);
|
||||
cell.find('.fa-search-minus').first().click();
|
||||
expect($scope.filter.calledTwice).to.be(true);
|
||||
cell.find('.fa-asterisk').first().click();
|
||||
expect($scope.filter.calledThrice).to.be(true);
|
||||
});
|
||||
|
||||
it('should NOT apply a filter when clicking non-filterable fields', function () {
|
||||
|
@ -115,6 +117,8 @@ describe('docViews', function () {
|
|||
expect($scope.filter.calledOnce).to.be(false);
|
||||
cell.find('.fa-search-minus').first().click();
|
||||
expect($scope.filter.calledTwice).to.be(false);
|
||||
cell.find('.fa-asterisk').first().click();
|
||||
expect($scope.filter.calledOnce).to.be(true);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -27,6 +27,15 @@
|
|||
tooltip-append-to-body="1"
|
||||
class="fa fa-columns"></i>
|
||||
</span>
|
||||
<span ng-if="!indexPattern.metaFields.includes(field)">
|
||||
<i ng-click="filter('_exists_', field, '+')"
|
||||
tooltip="Filter for field present"
|
||||
tooltip-append-to-body="1"
|
||||
class="fa fa-asterisk"></i>
|
||||
</span>
|
||||
<span ng-if="indexPattern.metaFields.includes(field)" tooltip="Unable to filter for presence of meta fields">
|
||||
<i class="fa fa-asterisk text-muted"></i>
|
||||
</span>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import ingest from './server/routes/api/ingest';
|
||||
import search from './server/routes/api/search';
|
||||
import settings from './server/routes/api/settings';
|
||||
|
||||
module.exports = function (kibana) {
|
||||
return new kibana.Plugin({
|
||||
|
@ -78,6 +79,7 @@ module.exports = function (kibana) {
|
|||
init: function (server, options) {
|
||||
ingest(server);
|
||||
search(server);
|
||||
settings(server);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -83,14 +83,15 @@ app.directive('dashboardGrid', function ($compile, Notifier) {
|
|||
});
|
||||
|
||||
$scope.$on('$destroy', function () {
|
||||
safeLayout.cancel();
|
||||
$window.off('resize', safeLayout);
|
||||
|
||||
if (!gridster) return;
|
||||
gridster.$widgets.each(function (i, el) {
|
||||
const panel = getPanelFor(el);
|
||||
removePanel(panel);
|
||||
// stop any animations
|
||||
panel.$el.stop();
|
||||
removePanel(panel, true);
|
||||
// not that we will, but lets be safe
|
||||
makePanelSerializeable(panel);
|
||||
});
|
||||
|
@ -125,9 +126,9 @@ app.directive('dashboardGrid', function ($compile, Notifier) {
|
|||
}
|
||||
|
||||
// tell gridster to remove the panel, and cleanup our metadata
|
||||
function removePanel(panel) {
|
||||
function removePanel(panel, silent) {
|
||||
// remove from grister 'silently' (don't reorganize after)
|
||||
gridster.remove_widget(panel.$el);
|
||||
gridster.remove_widget(panel.$el, silent);
|
||||
|
||||
// destroy the scope
|
||||
panel.$scope.$destroy();
|
||||
|
|
|
@ -118,6 +118,10 @@ app.directive('dashboardApp', function (Notifier, courier, AppState, timefilter,
|
|||
key: 'share',
|
||||
description: 'Share Dashboard',
|
||||
template: require('plugins/kibana/dashboard/partials/share.html')
|
||||
}, {
|
||||
key: 'options',
|
||||
description: 'Options',
|
||||
template: require('plugins/kibana/dashboard/partials/options.html')
|
||||
}];
|
||||
|
||||
$scope.refresh = _.bindKey(courier, 'fetch');
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
import angular from 'angular';
|
||||
import ngMock from 'ng_mock';
|
||||
import _ from 'lodash';
|
||||
|
@ -18,19 +17,20 @@ let config;
|
|||
let hits;
|
||||
let indexPattern;
|
||||
let indexPatternList;
|
||||
let shortDotsValue;
|
||||
|
||||
// Sets up the directive, take an element, and a list of properties to attach to the parent scope.
|
||||
const init = function ($elem, props) {
|
||||
ngMock.inject(function ($rootScope, $compile, $timeout, _config_) {
|
||||
shortDotsValue = _config_.get('shortDots:enable');
|
||||
config = _config_;
|
||||
config.set('shortDots:enable', false);
|
||||
$parentScope = $rootScope;
|
||||
_.assign($parentScope, props);
|
||||
$compile($elem)($parentScope);
|
||||
|
||||
// Required for test to run solo. Sigh
|
||||
$timeout(function () {
|
||||
$elem.scope().$digest();
|
||||
}, 0);
|
||||
$timeout(() => $elem.scope().$digest(), 0);
|
||||
|
||||
$scope = $elem.isolateScope();
|
||||
});
|
||||
|
@ -39,6 +39,7 @@ const init = function ($elem, props) {
|
|||
const destroy = function () {
|
||||
$scope.$destroy();
|
||||
$parentScope.$destroy();
|
||||
config.set('shortDots:enable', shortDotsValue);
|
||||
};
|
||||
|
||||
describe('discover field chooser directives', function () {
|
||||
|
@ -80,9 +81,7 @@ describe('discover field chooser directives', function () {
|
|||
$scope.$digest();
|
||||
}));
|
||||
|
||||
afterEach(function () {
|
||||
destroy();
|
||||
});
|
||||
afterEach(() => destroy());
|
||||
|
||||
const getSections = function (ctx) {
|
||||
return {
|
||||
|
@ -108,17 +107,26 @@ describe('discover field chooser directives', function () {
|
|||
|
||||
it('should have 2 popular fields, 1 unpopular field and no selected fields', function (done) {
|
||||
const section = getSections($elem);
|
||||
const popular = find('popular');
|
||||
const unpopular = find('unpopular');
|
||||
|
||||
expect(section.selected.find('li').length).to.be(0);
|
||||
|
||||
expect(section.popular.text()).to.contain('ssl');
|
||||
expect(section.popular.text()).to.contain('@timestamp');
|
||||
expect(section.popular.text()).to.not.contain('ip\n');
|
||||
expect(popular).to.contain('ssl');
|
||||
expect(popular).to.contain('@timestamp');
|
||||
expect(popular).to.not.contain('ip\n');
|
||||
|
||||
expect(section.unpopular.text()).to.contain('extension');
|
||||
expect(section.unpopular.text()).to.contain('machine.os');
|
||||
expect(section.unpopular.text()).to.not.contain('ssl');
|
||||
expect(unpopular).to.contain('extension');
|
||||
expect(unpopular).to.contain('machine.os');
|
||||
expect(unpopular).to.not.contain('ssl');
|
||||
done();
|
||||
|
||||
function find(popularity) {
|
||||
return section[popularity]
|
||||
.find('.discover-field-name')
|
||||
.map((i, el) => $(el).text())
|
||||
.toArray();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ import 'ui/filters/unique';
|
|||
import 'plugins/kibana/discover/components/field_chooser/discover_field';
|
||||
import _ from 'lodash';
|
||||
import $ from 'jquery';
|
||||
import rison from 'ui/utils/rison';
|
||||
import rison from 'rison-node';
|
||||
import fieldCalculator from 'plugins/kibana/discover/components/field_chooser/lib/field_calculator';
|
||||
import IndexPatternsFieldListProvider from 'ui/index_patterns/_field_list';
|
||||
import uiModules from 'ui/modules';
|
||||
|
|
|
@ -2,8 +2,8 @@ import _ from 'lodash';
|
|||
import angular from 'angular';
|
||||
import moment from 'moment';
|
||||
import getSort from 'ui/doc_table/lib/get_sort';
|
||||
import rison from 'ui/utils/rison';
|
||||
import dateMath from 'ui/utils/date_math';
|
||||
import rison from 'rison-node';
|
||||
import dateMath from '@elastic/datemath';
|
||||
import 'ui/doc_table';
|
||||
import 'ui/visualize';
|
||||
import 'ui/notify';
|
||||
|
|
|
@ -32,16 +32,15 @@ chrome
|
|||
lastUrlStore: window.sessionStorage,
|
||||
activeIndicatorColor: '#656a76'
|
||||
})
|
||||
.setRootController('kibana', function ($scope, $rootScope, courier, config) {
|
||||
function setDefaultTimezone() {
|
||||
moment.tz.setDefault(config.get('dateFormat:tz'));
|
||||
}
|
||||
|
||||
.setRootController('kibana', function ($scope, courier, config) {
|
||||
// wait for the application to finish loading
|
||||
$scope.$on('application.load', function () {
|
||||
courier.start();
|
||||
});
|
||||
|
||||
$scope.$on('init:config', setDefaultTimezone);
|
||||
$scope.$on('change:config.dateFormat:tz', setDefaultTimezone);
|
||||
config.watch('dateFormat:tz', setDefaultTimezone, $scope);
|
||||
|
||||
function setDefaultTimezone(tz) {
|
||||
moment.tz.setDefault(tz);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
import _ from 'lodash';
|
||||
import 'ui/elastic_textarea';
|
||||
import 'ui/filters/markdown';
|
||||
import ConfigDefaultsProvider from 'ui/config/defaults';
|
||||
import uiModules from 'ui/modules';
|
||||
import advancedRowTemplate from 'plugins/kibana/settings/sections/advanced/advanced_row.html';
|
||||
|
||||
uiModules.get('apps/settings')
|
||||
.directive('advancedRow', function (config, Notifier, Private) {
|
||||
.directive('advancedRow', function (config, Notifier) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
replace: true,
|
||||
|
@ -16,7 +15,6 @@ uiModules.get('apps/settings')
|
|||
configs: '='
|
||||
},
|
||||
link: function ($scope) {
|
||||
const configDefaults = Private(ConfigDefaultsProvider);
|
||||
const notify = new Notifier();
|
||||
const keyCodes = {
|
||||
ESC: 27
|
||||
|
@ -29,10 +27,10 @@ uiModules.get('apps/settings')
|
|||
const loading = function (conf, fn) {
|
||||
conf.loading = true;
|
||||
fn()
|
||||
.finally(function () {
|
||||
conf.loading = conf.editing = false;
|
||||
})
|
||||
.catch(notify.fatal);
|
||||
.then(function () {
|
||||
conf.loading = conf.editing = false;
|
||||
})
|
||||
.catch(notify.fatal);
|
||||
};
|
||||
|
||||
$scope.maybeCancel = function ($event, conf) {
|
||||
|
@ -51,7 +49,7 @@ uiModules.get('apps/settings')
|
|||
$scope.save = function (conf) {
|
||||
loading(conf, function () {
|
||||
if (conf.unsavedValue === conf.defVal) {
|
||||
return config.clear(conf.name);
|
||||
return config.remove(conf.name);
|
||||
}
|
||||
|
||||
return config.set(conf.name, conf.unsavedValue);
|
||||
|
@ -64,7 +62,7 @@ uiModules.get('apps/settings')
|
|||
|
||||
$scope.clear = function (conf) {
|
||||
return loading(conf, function () {
|
||||
return config.clear(conf.name);
|
||||
return config.remove(conf.name);
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@ import _ from 'lodash';
|
|||
import registry from 'ui/registry/settings_sections';
|
||||
import toEditableConfig from 'plugins/kibana/settings/sections/advanced/lib/to_editable_config';
|
||||
import 'plugins/kibana/settings/sections/advanced/advanced_row';
|
||||
import ConfigDefaultsProvider from 'ui/config/defaults';
|
||||
import uiRoutes from 'ui/routes';
|
||||
import uiModules from 'ui/modules';
|
||||
import indexTemplate from 'plugins/kibana/settings/sections/advanced/index.html';
|
||||
|
@ -17,39 +16,25 @@ uiModules.get('apps/settings')
|
|||
return {
|
||||
restrict: 'E',
|
||||
link: function ($scope) {
|
||||
const configDefaults = Private(ConfigDefaultsProvider);
|
||||
const keyCodes = {
|
||||
ESC: 27
|
||||
};
|
||||
|
||||
function isTypeComplex(conf) {
|
||||
return !(conf.json || conf.array || conf.bool || conf.normal);
|
||||
}
|
||||
|
||||
function notDefaultConfig(configName) {
|
||||
return !(configName in configDefaults);
|
||||
}
|
||||
|
||||
function readConfigVals() {
|
||||
const configVals = config._vals();
|
||||
|
||||
const customConfig = Object.keys(configVals)
|
||||
.filter(notDefaultConfig)
|
||||
.map(name => toEditableConfig(false, name, configVals[name]));
|
||||
|
||||
$scope.configs = _(configDefaults)
|
||||
.map((def, name) => toEditableConfig(def, name, configVals[name]))
|
||||
.reject('readonly')
|
||||
.concat(customConfig)
|
||||
.value();
|
||||
}
|
||||
|
||||
// react to changes of the config values
|
||||
const unhook = $rootScope.$on('change:config', readConfigVals);
|
||||
$scope.$on('$destroy', unhook);
|
||||
config.watchAll(changed, $scope);
|
||||
|
||||
// initial config setup
|
||||
readConfigVals();
|
||||
changed();
|
||||
|
||||
function changed(values) {
|
||||
const all = config.getAll();
|
||||
const editable = _(all)
|
||||
.map((def, name) => toEditableConfig({
|
||||
def,
|
||||
name,
|
||||
value: def.userValue,
|
||||
isCustom: config.isCustom(name)
|
||||
}))
|
||||
.value();
|
||||
const writable = _.reject(editable, 'readonly');
|
||||
$scope.configs = writable;
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
|
|
@ -82,5 +82,5 @@ describe('Settings', function () {
|
|||
});
|
||||
|
||||
function invoke({ def = false, name = 'woah', value = 'forreal' } = {}) {
|
||||
return toEditableConfig(def, name, value);
|
||||
return toEditableConfig({ def, name, value, isCustom: def === false });
|
||||
}
|
||||
|
|
|
@ -8,10 +8,10 @@ import getEditorType from './get_editor_type';
|
|||
* @param {object} current value of setting
|
||||
* @returns {object} the editable config object
|
||||
*/
|
||||
function toEditableConfig(def, name, value) {
|
||||
const isCustom = !def;
|
||||
if (isCustom) def = {};
|
||||
|
||||
function toEditableConfig({ def, name, value, isCustom }) {
|
||||
if (!def) {
|
||||
def = {};
|
||||
}
|
||||
const conf = {
|
||||
name,
|
||||
value,
|
||||
|
|
|
@ -56,7 +56,7 @@ uiModules.get('apps/settings')
|
|||
|
||||
$scope.removePattern = function () {
|
||||
if ($scope.indexPattern.id === config.get('defaultIndex')) {
|
||||
config.delete('defaultIndex');
|
||||
config.remove('defaultIndex');
|
||||
if (otherIds.length) {
|
||||
config.set('defaultIndex', otherIds[0]);
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ uiModules
|
|||
$scope.delete = attrs.delete ? $scope.delete : null;
|
||||
$scope.setDefault = attrs.setDefault ? $scope.setDefault : null;
|
||||
$scope.refreshFields = attrs.refreshFields ? $scope.refreshFields : null;
|
||||
config.$bind($scope, 'defaultIndex');
|
||||
config.bindToScope($scope, 'defaultIndex');
|
||||
}
|
||||
};
|
||||
});
|
||||
|
|
|
@ -27,7 +27,7 @@ uiModules.get('apps/settings')
|
|||
template: indexTemplate,
|
||||
link: function ($scope) {
|
||||
$scope.editingId = $route.current.params.indexPatternId;
|
||||
config.$bind($scope, 'defaultIndex');
|
||||
config.bindToScope($scope, 'defaultIndex');
|
||||
|
||||
$scope.$watch('defaultIndex', function () {
|
||||
const ids = $route.current.locals.indexPatternIds;
|
||||
|
|
|
@ -3,7 +3,11 @@
|
|||
<div class="header">
|
||||
<h2 class="title">Edit Saved Objects</h2>
|
||||
<button class="btn btn-default controls" ng-click="exportAll()"><i aria-hidden="true" class="fa fa-download"></i> Export Everything</button>
|
||||
<button file-upload="importAll(fileContents)" class="btn btn-default controls" ng-click><i aria-hidden="true" class="fa fa-upload"></i> Import</button>
|
||||
<file-upload on-read="importAll(fileContents)" upload-selector="button.upload">
|
||||
<button class="btn btn-default controls upload" ng-click>
|
||||
<i aria-hidden="true" class="fa fa-upload"></i> Import
|
||||
</button>
|
||||
</file-upload>
|
||||
</div>
|
||||
<p>
|
||||
From here you can delete saved objects, such as saved searches. You can also edit the raw data of saved objects. Typically objects are only modified via their associated application, which is probably what you should use instead of this screen. Each tab is limited to 100 results. You can use the filter to find objects not in the default list.
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import { saveAs } from '@spalger/filesaver';
|
||||
import _ from 'lodash';
|
||||
import { extend, find, flattenDeep, partialRight, pick, pluck, sortBy } from 'lodash';
|
||||
import angular from 'angular';
|
||||
import registry from 'plugins/kibana/settings/saved_object_registry';
|
||||
import objectIndexHTML from 'plugins/kibana/settings/sections/objects/_objects.html';
|
||||
import 'ui/directives/file_upload';
|
||||
import uiRoutes from 'ui/routes';
|
||||
import uiModules from 'ui/modules';
|
||||
const MAX_SIZE = Math.pow(2, 31) - 1;
|
||||
|
||||
const MAX_SIZE = Math.pow(2, 31) - 1;
|
||||
|
||||
uiRoutes
|
||||
.when('/settings/objects', {
|
||||
|
@ -41,9 +41,9 @@ uiModules.get('apps/settings')
|
|||
});
|
||||
|
||||
$q.all(services).then(function (data) {
|
||||
$scope.services = _.sortBy(data, 'title');
|
||||
$scope.services = sortBy(data, 'title');
|
||||
let tab = $scope.services[0];
|
||||
if ($state.tab) $scope.currentTab = tab = _.find($scope.services, {title: $state.tab});
|
||||
if ($state.tab) $scope.currentTab = tab = find($scope.services, {title: $state.tab});
|
||||
|
||||
$scope.$watch('state.tab', function (tab) {
|
||||
if (!tab) $scope.changeTab($scope.services[0]);
|
||||
|
@ -83,23 +83,23 @@ uiModules.get('apps/settings')
|
|||
};
|
||||
|
||||
$scope.bulkDelete = function () {
|
||||
$scope.currentTab.service.delete(_.pluck($scope.selectedItems, 'id')).then(refreshData).then(function () {
|
||||
$scope.currentTab.service.delete(pluck($scope.selectedItems, 'id')).then(refreshData).then(function () {
|
||||
$scope.selectedItems.length = 0;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.bulkExport = function () {
|
||||
const objs = $scope.selectedItems.map(_.partialRight(_.extend, {type: $scope.currentTab.type}));
|
||||
const objs = $scope.selectedItems.map(partialRight(extend, {type: $scope.currentTab.type}));
|
||||
retrieveAndExportDocs(objs);
|
||||
};
|
||||
|
||||
$scope.exportAll = () => {
|
||||
Promise.map($scope.services, (service) =>
|
||||
service.service.scanAll('').then((results) =>
|
||||
results.hits.map((hit) => _.extend(hit, {type: service.type}))
|
||||
)
|
||||
).then((results) => retrieveAndExportDocs(_.flattenDeep(results)));
|
||||
};
|
||||
$scope.exportAll = () => Promise
|
||||
.map($scope.services, service => service.service
|
||||
.scanAll('')
|
||||
.then(result => result.hits.map(hit => extend(hit, { type: service.type })))
|
||||
)
|
||||
.then(results => retrieveAndExportDocs(flattenDeep(results)))
|
||||
.catch(error => notify.error(error));
|
||||
|
||||
function retrieveAndExportDocs(objs) {
|
||||
if (!objs.length) return notify.error('No saved objects to export.');
|
||||
|
@ -108,7 +108,7 @@ uiModules.get('apps/settings')
|
|||
body: {docs: objs.map(transformToMget)}
|
||||
})
|
||||
.then(function (response) {
|
||||
saveToFile(response.docs.map(_.partialRight(_.pick, '_id', '_type', '_source')));
|
||||
saveToFile(response.docs.map(partialRight(pick, '_id', '_type', '_source')));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -131,7 +131,7 @@ uiModules.get('apps/settings')
|
|||
}
|
||||
|
||||
return Promise.map(docs, function (doc) {
|
||||
const service = _.find($scope.services, {type: doc._type}).service;
|
||||
const service = find($scope.services, {type: doc._type}).service;
|
||||
return service.get().then(function (obj) {
|
||||
obj.id = doc._id;
|
||||
return obj.applyESResp(doc).then(function () {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import _ from 'lodash';
|
||||
import angular from 'angular';
|
||||
import rison from 'ui/utils/rison';
|
||||
import rison from 'rison-node';
|
||||
import registry from 'plugins/kibana/settings/saved_object_registry';
|
||||
import objectViewHTML from 'plugins/kibana/settings/sections/objects/_view.html';
|
||||
import IndexPatternsCastMappingTypeProvider from 'ui/index_patterns/_cast_mapping_type';
|
||||
|
|
|
@ -241,6 +241,8 @@ uiModules
|
|||
|
||||
$scope.doSave = function () {
|
||||
savedVis.id = savedVis.title;
|
||||
// vis.title was not bound and it's needed to reflect title into visState
|
||||
$state.vis.title = savedVis.title;
|
||||
savedVis.visState = $state.vis;
|
||||
savedVis.uiStateJSON = angular.toJson($scope.uiState.getChanges());
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue